ver*_*tas 19 java concurrency multithreading concurrenthashmap
新版本的jdk 8的Concurrent Hash Map有两个新方法.
computeIfAbsent
computeIfPresent
putIfAbsent - 旧方法
我理解putIfAbsent和computeIfAbsent的用例.但我不确定何时使用computeIfPresent.另外,如果我现在有computeIfPresent,为什么还需要putIfAbsent. putIfAbsent会创建至少一个额外的值实例.
原因只是具有向后兼容性吗?
Mar*_*o13 33
正如在另一个答案中所提到的:即使引入了新的,更强大的"方法",也始终保留方法以实现向后兼容.
关于用例computeIfPresent:可能很难找到一个足够小的例子,看起来不做作,但仍然令人信服.通常,此方法的目的是以任何形式更新现有值.
一个例子可以是(约束的)字数:对于给定的一组字,一个存储0地图中的初始计数.然后,处理一系列单词:每当从初始集中找到一个单词时,其计数增加1:
import java.util.LinkedHashMap;
import java.util.Map;
public class ComputeIfPresentExample
{
public static void main(String[] args)
{
Map<String, Integer> wordCounts = new LinkedHashMap<String, Integer>();
String s =
"Lorem ipsum dolor sit amet consetetur iam nonumy sadipscing " +
"elitr, sed diam nonumy eirmod tempor invidunt ut erat sed " +
"labore et dolore magna dolor sit amet aliquyam erat sed diam";
wordCounts.put("sed", 0);
wordCounts.put("erat", 0);
for (String t : s.split(" "))
{
wordCounts.computeIfPresent(t, (k,v) -> v+1);
}
System.out.println(wordCounts);
}
}
Run Code Online (Sandbox Code Playgroud)
(当然,这样的事情可以用不同的方式解决,但这是一种相当频繁的任务形式,新方法允许一个相当简洁和优雅的解决方案)
一个常见的用例是带有collection的地图,例如
Map<String, Collection<String>> strings = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
computeIfAbsent并且computeIfPresent是用于向集合中添加元素或从集合中删除元素的非常方便的操作。这是一个按字符串的第一个字符分组的示例。请注意,密钥和集合都在必要时创建,并在集合为空时将其清除:
void addString(String a) {
String index = a.substring(0, 1);
strings.computeIfAbsent(index, ign -> new HashSet<>()).add(a);
}
void removeString(String a) {
String index = a.substring(0, 1);
strings.computeIfPresent(index, (k, c) -> {
c.remove(a);
return c.isEmpty() ? null : c;
});
}
Run Code Online (Sandbox Code Playgroud)
例:
// {}
addString("a1"); // {a=[a1]} <-- collection dynamically created
addString("a2"); // {a=[a1, a2]}
removeString("a1"); // {a=[a2]}
removeString("a2"); // {} <-- both key and collection removed
Run Code Online (Sandbox Code Playgroud)
这在多线程环境中非常强大,因为ConcurrentMaps可以自动执行这些操作。
删除操作可以是单行的:
void removeString(String a) {
String index = a.substring(0, 1);
strings.computeIfPresent(index, (i, c) -> c.remove(a) && c.isEmpty() ? null : c);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
26873 次 |
| 最近记录: |