这是我的简单代码:
public class Main2 {
public static void main(String[] args) {
HashMap<String, Integer> map = new HashMap<String, Integer>();
List<String> names = Arrays.asList("love", "love", "like", "feel", "else");
names.forEach(s -> {
map.putIfAbsent(s, 0);
map.computeIfAbsent(s, v -> map.get(v) + 1);
});
map.forEach((k, v) -> {
System.out.println(String.format("Found key : %s, with value: %s", k, v));
});
}
}
我想计算每个单词在该列表中的存在次数,但是当我打印它时,输出始终为零
输出:
Found key : love, with value: 0
Found key : like, with value: 0
Found key : else, with value: 0
Found key : feel, with value: 0
答案 0 :(得分:4)
names.forEach(s -> {
map.putIfAbsent(s, 0);
map.computeIfPresent(s, (word, count) -> count + 1);
});
但是正如davidxxx正确指出的那样,它效率不高。可以用Map::merge
的单一用法代替它:
names.forEach(s -> {
map.merge(s, 1, Integer::sum);
});
答案 1 :(得分:3)
对于每个不存在的密钥,您put
的值为0
,因此computeIfAbsent
不执行任何操作(因为不存在密钥),并且所有值都保留为0
。
您可以写:
names.forEach(s -> {
map.putIfAbsent(s, 0);
map.put(s,map.get(s) + 1);
});
或更简单:
names.forEach(s -> {
map.put(s,map.getOrDefault(s,0) + 1);
});
答案 2 :(得分:1)
好像您想计算集合中遇到单词的次数。
如果是这样,那为什么不这样呢?
List<String> words = Arrays.asList("love", "love", "like", "feel", "else");
Map<String, Long> map = words.stream()
.collect(Collectors.groupingBy(
Function.identity(),
Collectors.counting()
));
这里唯一的区别是它使用Long
来存储计数器。如果您对此表示不满意,则从某种意义上说,您的Map
类型是固定的,您可以替换
Collectors.counting()
使用
Collectors.summingInt(e -> 1)
这会给你Map<String, Integer>
。
答案 3 :(得分:1)
Map.merge()
是最简单,最有效的方法。
请注意,此处的流也很好(避免显式创建地图):
Map<String, Integer> map =
names.stream()
.collect(toMap(s -> s, o -> 1, (v1, v2) -> v1 + v2));
或更直的方法引用sum:
Map<String, Integer> map =
names.stream()
.collect(toMap(s -> s, o -> 1, Integer::sum));