在 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()));
Run Code Online (Sandbox Code Playgroud)
此外,文档Map.Entry.setValue
不支持批量操作;所以拥有Map.Entry
过于简单的键值的好处似乎被打败了。
.... 在计算过程中可能会暂时改变;除了 forEach 操作,理想情况下应该是无副作用的。
Map.Entry
对象上的批量操作不支持 methodsetValue
。
因此 IMO 两种方法可以互换使用(除非我错过了一些非常明显的东西)
所以我的问题是
唯一的区别是,一个接受 BiConsumer,另一个只接受 Consumer。
这里是相关代码:
// 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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
不知何故,有两种设置组件大小的方法:setSize(Dimension)
和setSize(int, int)