【问题标题】:How to get ComputeIfPresent working with Map within Map?如何让 ComputeIfPresent 在地图中使用地图?
【发布时间】:2018-10-03 11:05:28
【问题描述】:

当尝试使用 computeIfPresent() 方法更改地图时,我在使用 innerMap 时无法实现此方法。

这行得通:

Map<String, Integer> mapOne = new HashMap<>();
mapOne.computeIfPresent(key, (k, v) -> v + 1);

这不起作用:

Map<String, Map<String, Integer>> mapTwo = new HashMap<>();
mapTwo.computeIfPresent(key, (k, v) -> v.computeIfPresent(anotherKey, (x, y) -> y + 1);

在第二个示例中,我收到以下错误消息:“lambda 表达式中的返回类型错误:整数无法转换为 Map&lt;String, Integer&gt;”。 我的 IDE 将 v 识别为 Map。但是这个功能不起作用。

显然该方法返回一个整数,但我看不出这与没有 Innermap 的第一个方法有何不同。目前我还没有在网上找到类似的案例。

我怎样才能让它工作?

【问题讨论】:

  • 在第一个示例中,映射的类型为&lt;String, Integer&gt;,因此返回的 lambda 函数和整数很好。但是,在第二个示例中,映射的类型为 &lt;String, Map&gt;,因此 lambda 函数应返回映射......而不是整数。

标签: java dictionary hashmap


【解决方案1】:

有点离题(有点),但对相同的地图做同样的事情,以神秘的方式中断:

// breaks with ConcurrentModificationException
Map<String, Integer> test = new HashMap<>(); // or  = new Hashtable<>();
test.computeIfAbsent("one", x -> test.computeIfAbsent("one", y -> 1));

// IllegalStateException: Recursive update
Map<String, Integer> test = new ConcurrentHashMap<>();
// ... same code

// the only one that works correctly that I am aware of
Map<String, Integer> test = new ConcurrentSkipListMap<>();

【讨论】:

    【解决方案2】:

    为了了解您的问题,让我们看一下您正在使用的方法的签名:

    V computeIfPresent(K key, BiFunction&lt;? super K,? super V,? extends V&gt; remappingFunction)

    如您所见,它返回基于V 泛型参数的类型,该参数代表存储在Map 中的值。这就是您面临问题的地方:您的内部映射存储Integer,因此当您调用computeIfPresent 时,您会得到Integer,而您的外部映射需要另一个Map

    编辑:
    在写作的时候,我意识到 Eran 已经给出了一个代码示例来说明如何做到这一点。
    但我会留下这个答案,因为它解释了为什么你的方法不起作用,所以它可能会对某人有所帮助。

    【讨论】:

      【解决方案3】:

      外部 lambda 表达式应返回 v 引用的 Map

      mapTwo.computeIfPresent(key, 
                              (k, v) -> {
                                      v.computeIfPresent(anotherKey, (x, y) -> y + 1); 
                                      return v;
                                  });
      

      它不能返回表达式v.computeIfPresent(anotherKey, (x, y) -&gt; y + 1);Integer值。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-12-08
        • 2011-10-30
        • 2021-04-15
        • 2013-06-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多