为什么map.merge()每次都不调用重映射函数?

时间:2017-07-13 03:47:56

标签: java lambda java-8 hashmap

Map.merge()文档说:

  

如果指定的键尚未与值关联或是   与null关联,将其与给定的非null值相关联。   否则,将相关值替换为给定的结果   重新映射函数,如果结果为null则删除。这种方法可以   在组合键的多个映射值时使用。对于   例如,要创建或附加String msg到值映射。

例如,此代码应计算一篮子中每种类型的果实数量:

public static void main(String[] args) {
    Map<String, Integer> fruitCounts = new HashMap<>();
    List<String> fruitBasket = Arrays.asList(
        "Apple", "Banana", "Apple", "Orange", "Mango", "Orange", "Mango", "Mango");
    for (String fruit : fruitBasket) {
        fruitCounts.merge(fruit, 1/*First fruit of this type*/, (k, v) -> v + 1);
    }
    System.out.println(fruitCounts);
}

有2个苹果,3个芒果,2个橙子和1个香蕉,但实际产量是:

{Apple=2, Mango=2, Orange=2, Banana=1}

有什么问题?

2 个答案:

答案 0 :(得分:7)

问题出在这里

(k, v) -> v + 1

你应该这样做

(k, v) -> k + v

如果检查合并的实现,它会说remappingFunction.apply(oldValue, value);表示现有值将是第一个参数,您应该在其中添加初始化它的相同数字,作为该函数的第二个参数。< / p>

<强>更新

答案 1 :(得分:5)

完成@Mritunjay的回答,这里是使用compute的等效文件,您可以在其中看到差异:

fruitCounts.compute(fruit, (k,v) -> v == null ? 1 : v + 1) //computing over the value
fruitCounts.merge(fruit, 1, (oldValue, newValue) -> oldValue + 1) //merging over the value