在Java 8 ConcurrentHashMap
中引入了两个新方法即。 forEach
和forEachEntry
。
仔细看看它们两个都有相同的论点 - forEach
有关键&当BiConsumer
forEachEntry
Map.Entry
通过Consumer
提供ConcurrentHashMap<String, Integer> map = Stream.of("One", "Two", "Three", "Four", "Five").
collect(Collectors.toConcurrentMap( str -> str,
str -> str.length(),
(str, len) -> len,
ConcurrentHashMap::new));
map.forEach(1, (k, v) -> System.out.println(k + " " + v));
map.forEachEntry(1, entry -> System.out.println(entry.getKey() + " " + entry.getValue()));
时提供的价值来自密钥&amp;价值可以得出。
打印所有地图条目的简单用例可以通过以下任一方式实现,如下所示
Map.Entry.setValue
此外,从文档中Map.Entry
不支持批量操作;因此,使Map.Entry
超过普通键值的好处似乎被打败了。
....在计算过程中可能会暂时改变;除了forEach动作外,理想情况下应该是无副作用的。对
setValue
个对象的批量操作执行 支持方法array:3 [▼ 0 => array:2 [▼ "x" => "Kasaa" "y" => "8" ] 1 => array:2 [▼ "x" => "Pasa" "y" => "9" ] 2 => array:2 [▼ "x" => "tasa" "y" => "8" ] ]
。
因此,IMO两种方法可以互换使用(除非我错过了一些非常明显的)
所以我的问题是
答案 0 :(得分:4)
唯一不同的是,一个接受BiConsumer而另一个只接受消费者。
这里有相关代码:
// forEach
static final class ForEachMappingTask<K,V>
extends BulkTask<K,V,Void> {
final BiConsumer<? super K, ? super V> action;
ForEachMappingTask
(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
BiConsumer<? super K,? super V> action) {
super(p, b, i, f, t);
this.action = action;
}
public final void compute() {
final BiConsumer<? super K, ? super V> action;
if ((action = this.action) != null) {
for (int i = baseIndex, f, h; batch > 0 &&
(h = ((f = baseLimit) + i) >>> 1) > i;) {
addToPendingCount(1);
new ForEachMappingTask<K,V>
(this, batch >>>= 1, baseLimit = h, f, tab,
action).fork();
}
for (Node<K,V> p; (p = advance()) != null; )
action.accept(p.key, p.val);
propagateCompletion();
}
}
}
// forEachEntry
static final class ForEachEntryTask<K,V>
extends BulkTask<K,V,Void> {
final Consumer<? super Entry<K,V>> action;
ForEachEntryTask
(BulkTask<K,V,?> p, int b, int i, int f, Node<K,V>[] t,
Consumer<? super Entry<K,V>> action) {
super(p, b, i, f, t);
this.action = action;
}
public final void compute() {
final Consumer<? super Entry<K,V>> action;
if ((action = this.action) != null) {
for (int i = baseIndex, f, h; batch > 0 &&
(h = ((f = baseLimit) + i) >>> 1) > i;) {
addToPendingCount(1);
new ForEachEntryTask<K,V>
(this, batch >>>= 1, baseLimit = h, f, tab,
action).fork();
}
for (Node<K,V> p; (p = advance()) != null; )
action.accept(p);
propagateCompletion();
}
}
}
以某种方式设置组件大小的两种方法:setSize(Dimension)
和setSize(int, int)
答案 1 :(得分:4)
我认为这只是一个方便的问题,例如我更喜欢让密钥成为必须始终调用getKey()/ getValue()的参数intead中的值。实际上我甚至没有使用/关注forEach函数,一旦你在函数式编程中变得更加老练,你就会知道这种函数是迄今为止最不实用的FP,所以像Haskell这样的纯函数语言甚至都没有拥有他们。你期望用forEach做的一切,你可以做map / reduce / collect,没有任何副作用。
BtW:为方便起见,发布了指向Javadoc的链接。 https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ConcurrentHashMap.html
答案 2 :(得分:0)
显然没有功能差异。它只是一个多元化的API,让开发人员感到舒适。通常,您为操作使用(k,v)参数,但有时,您可能正在操纵条目实例并将其推送到其他消耗条目的其他API&lt;&gt;对象。 不幸的是,我无法弄清楚任何一个例子,但由于Entry是地图的内部类,它也可以访问地图的某些成员,条目存储在。