如果条件失败,我正尝试将HashMap
中的所有值重置为某个默认值。
目前我通过迭代所有键并单独重置值来实现这一点。
有没有可能的方法为所有键设置相同的值而不进行迭代?
类似的东西:
hm.putAll("some val") //hm is hashmap object
答案 0 :(得分:6)
您无法避免迭代,但如果您使用java-8,则可以使用replaceAll
方法为您执行此操作。
将指定的函数应用于此映射中的每个条目,替换每个条目 条目的值与调用函数的函数#map的结果 使用当前条目的键和值的方法。
m.replaceAll((k,v) -> yourDefaultValue);
基本上它迭代遍历映射表的每个节点,并影响每个值的函数返回值。
@Override
public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
Node<K,V>[] tab;
if (function == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
for (int i = 0; i < tab.length; ++i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next) {
e.value = function.apply(e.key, e.value); //<-- here
}
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
示例:
public static void main (String[] args){
Map<String, Integer> m = new HashMap<>();
m.put("1",1);
m.put("2",2);
System.out.println(m);
m.replaceAll((k,v) -> null);
System.out.println(m);
}
输出:
{1=1, 2=2}
{1=null, 2=null}
答案 1 :(得分:5)
你不能以某种方式避免迭代。
您可以通过Map.values()获取值并迭代这些值。您可以绕过按键查找,它可能是最有效的解决方案(尽管我怀疑通常会为您节省相对较少,也许对于您的代码的随意读者来说,这不是最明显的)
答案 2 :(得分:1)
恕我直言你必须创建自己的数据结构,从谷歌扩展。然后你可以编写你的方法resetAll()并给出默认值。 Map是一个快速平衡的树,允许您快速地在结构中行走并设置值。不用担心速度,因为树在重置之前和之后将具有相同的结构。 只是,小心并发线程。也许你应该使用ConcurrentHashMap。
public class MyMap<K,V> extends ConcurrentHashMap<K, V>{
public void resetAll(V value){
Iterator<Entry<K, V>> it = this.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pairs = (Map.Entry)it.next();
pairs.setValue( value );
}
}
}
此致
答案 3 :(得分:0)
如果你愿意复制它(带有默认值的hashmap) 您可以先清除哈希值,然后移动默认值
hm.keySet().removeAll();
hm.putAll(defaultMap);
答案 4 :(得分:0)
不可能在小于O(n)
时间内对集合中的所有值应用操作,但是如果您的异议本身就是迭代本身,则有一些可能的替代方案,特别是函数式编程。
Guava库(或原生于Java 8)和functional programming utilities使这变得最容易。他们的Maps.transformValues()
提供了地图的视图,并应用了提供的功能。这意味着函数在O(1)
时间内返回,与迭代不同,但只要从返回的映射中.get()
,计算就会立即完成。这显然是一种权衡 - 如果您只需要.get()
转换后的地图中的某些元素,您可以通过避免计算不必要的值来节省时间。另一方面,如果你知道你以后会至少击中每个元素一次,使用这种行为意味着你实际上会浪费时间。实质上,这种方法是O(k)
,其中k
是您计划执行的查找次数。如果k
始终小于n
,则使用转换方法是最佳的。
仔细阅读页面顶部的警告;迭代是一种简单,易用且通常理想有效的方式来处理地图成员。你应该只在绝对必要时尝试优化过去。
答案 5 :(得分:0)
假设你的问题不在于自己进行迭代,而是因为O(n)在某个时刻正在进行,我建议采用几种替代方法。请记住,我不知道你使用的是什么,所以它对你没有任何意义。
案例A :如果您的密钥组已知且已预先修复,请在某处复制(不是参考,实际克隆),并将值重置为您想要的值。然后在你提到的那个条件下,只需切换引用即可使用默认值。
案例B :如果密钥随时间变化,请使用案例A中的提示,但为添加的每个新密钥添加新条目(或相应删除)。您的更新几乎不会被注意到,但您仍然可以切换回O(1)中的默认值。