java使用compuateifpresent计算哈希映射不起作用

时间:2019-09-01 09:59:31

标签: java

这是我的简单代码:

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

4 个答案:

答案 0 :(得分:4)

改为使用Map::computeIfPresent

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));