【问题标题】:Java8 stream operations on nested maps - Map<String, List<Map>>嵌套地图上的 Java8 流操作 - Map<String, List<Map>>
【发布时间】:2018-05-07 11:21:29
【问题描述】:

我有以下类型的Map - Map&lt;String, List&lt;Map&lt;String, String&gt;&gt;&gt;。它包含以下格式的元素:

"1" - [M1, M1, M3]
"2" - [M1, M2, M3]
"3" - [M4]
"4" - [M2, M5]

在哪里,

"1","2","3","4"Map&lt;<b>String</b>, List&lt;Map&lt;String, String&gt;&gt;&gt; 的外层映射的键。让我们称他们为outerKey。所以,M1outerKeys 都是"1", "2"。对于M2,它是"2", "4",等等。

M1, M2, M3, M4, M5Map&lt;String, List&lt;<b>Map&lt;String, String&gt;</b>&gt;&gt;的内部映射

区分内部映射的主键是k1键。 (除了k1,内部映射中还有其他条目)。例如:

M1 - { "k1": "m1", "k2": "n1" }M2 - { "k1": "m2", "k2": "n2" }

现在,我想提取一个独特的内部地图列表以及它的最高值outerKey。例如,对于上述输入,输出应为:

M1 - "2"
M2 - "4"
M3 - "2"
M4 - "3"
M5 - "4"

outerKey 也可以插入到地图中,这样我们就可以获得地图列表。

所以,对于样本输入:

    {
    	"1": [{
    		"k1": "m1",
    		"k2": "n1"
    	}, {
    		"k1": "m1",
    		"k2": "n1"
    	}, {
    		"k1": "m2",
    		"k2": "n2"
    	}],
    	"2": [{
    		"k1": "m1",
    		"k2": "n1"
    	}, {
    		"k1": "m2",
    		"k2": "n2"
    	}, {
    		"k1": "m3",
    		"k2": "n3"
    	}],
    	"3": [{
    		"k1": "m4",
    		"k2": "n4"
    	}],
    	"4": [{
    		"k1": "m2",
    		"k2": "n2"
    	}, {
    		"k1": "m5",
    		"k2": "n5"
    	}]
    }

Use the following code to convert it into Map:

(JSONObject)JSONValue.parseWithException(data)

输出将是:

[{
    	"k1": "m1",
    	"k2": "n1",
    	"outerKey": "2"
    }, {
    	"k1": "m2",
    	"k2": "n2",
    	"outerKey": "4"
    }, {
    	"k1": "m3",
    	"k2": "n3",
    	"outerKey": "2"
    }, {
    	"k1": "m4",
    	"k2": "n4",
    	"outerKey": "3"
    }, {
    	"k1": "m5",
    	"k2": "n5",
    	"outerKey": "4"
    }]

我在 java8 中遇到了一些麻烦?

我尝试通过执行以下操作来获取Map&lt;String, String&gt; 的流并同时添加条目(outerKey):

a.entrySet().stream().flatMap(e -> e.getValue().stream(m -> m.put("outerKey",e.getKey())))

但它返回一个Stream&lt;String&gt;,因为map.put 返回与键关联的先前值。

因此,我无法获得添加了 entryStream&lt;Map&gt;。我哪里错了?

【问题讨论】:

  • 到目前为止你有什么尝试?
  • @Downvoters:对你们来说,这似乎是一个非常琐碎的问题。可能不适合其他人。也许这就是我问的原因?
  • 我没有仔细阅读它,但是如果你想要Stream&lt;Map...&gt;m -&gt; { m.put("outerKey",e.getKey(); return m;}) 将不起作用?
  • m -&gt; {m.put("outerKey",e.getKey());return m;} 我想这应该可行。为什么它不起作用?
  • 因为至少你会把这个条目放太多次,你可能在这里寻找Collectors.collectingAndThen

标签: java-8 hashmap java-stream


【解决方案1】:

以下作品:

a.entrySet()
            .stream()
            .flatMap(e -> e.getValue().stream().map(m -> {m.put("outerKey",e.getKey());return m;}))
            .collect(
                groupingBy(m -> m.get("k1"),collectingAndThen(maxBy(comparing(m -> m.get("outerKey"))),o -> ((Optional)o).get())
                )
            )
            .values()

输出:

[{outerKey=2, k1=m1, k2=n1}, {outerKey=4, k1=m2, k2=n2}, {outerKey=2, k1=m3, k2=n3}, {outerKey=3, k1=m4, k2=n4}, {outerKey=4, k1=m5, k2=n5}]

【讨论】: