How to Convert a Map<String, List<List<String>>> to Map<String, List<String>> in java 8 functional APIs

huangapple go评论58阅读模式
英文:

How to Convert a Map<String, List<List<String>>> to Map<String, List<String>> in java 8 functional APIs

问题

我有一个这样的类;

class: {
   id: &quot;&quot;,
   sub: [{
       type: 1,
       value: &quot;&quot;
   }]
}

现在,我想按id首先分组类;

class.stream().collect(Collectors.groupingBy(class::id))

然后我想将子值平铺到List&lt;String&gt;,我有以下内容:

class.stream().collect(Collectors.groupingBy(class::id,
  Collectors.mapping(e -&gt;
    e.sub().stream()
      .filter(v -&gt; v.type().equals(1))
       .map(sub::value),
    Collectors.toList()
  )))

它返回一个Map&lt;String, List&lt;List&lt;String&gt;&gt;&gt;

那么,我如何将Map&lt;String, List&lt;List&lt;String&gt;&gt;&gt;转换为Map&lt;String, List&lt;String&gt;&gt;,使用Java 8函数API?

英文:

I have a class like this;

class: {
   id: &quot;&quot;,
   sub: [{
       type: 1,
       value: &quot;&quot;
   }]
}

Now, I want group class first by id;

class.stream().collect(Collectors.groupingBy(class::id))

Then I want flat sub-value to a List&lt;String&gt;, I have the following:

class.stream().collect(Collectors.groupingBy(class::id,
  Collectors.mapping(e -&gt;
    e.sub().stream()
      .filter(v -&gt; v.type().equals(1))
       .map(sub::value),
    Collectors.toList()
  )))

It returns a Map&lt;String, List&lt;List&lt;String&gt;&gt;&gt;

So, how can I convert a Map&lt;String, List&lt;List&lt;String&gt;&gt;&gt; to Map&lt;String, List&lt;String&gt;&gt; using the Java 8 functional API?

答案1

得分: 1

您可以使用Map收集器按键分组并合并值。

示例(Java 14及以上):

class Test {

	// 示例数据类型
	record Sub(int type, String value) {}
    record Clazz(String id, List<Sub> sub) {}

	public static void main(String[] args) {
		// 示例数据
		List<Clazz> classes = List.of(
			new Clazz("id1", List.of(new Sub(1, "A"), new Sub(2, "B"))),
			new Clazz("id2", List.of(new Sub(3, "C"), new Sub(4, "D"))),
			new Clazz("id1", List.of(new Sub(5, "E"), new Sub(6, "A")))
		);

		Map<String, List<String>> map = classes.stream()
			.collect(Collectors.toMap(
				// 新地图的键: c.id
				c -> c.id,

				// 新地图的值: c.sub[].value 作为列表
				c -> c.sub.stream().map(s -> s.value).toList(),

				// 重复值合并(分组): 合并两个值列表,无重复项
				(v1, v2) -> Stream.concat(v1.stream(), v2.stream()).distinct().toList()
			));

		// 打印生成的数据
		map.forEach((k, v) -> System.out.println(k + " -> " + String.join(",", v)));
	}
}

输出:

id2 -> C,D
id1 -> A,B,E
英文:

You can use the Map collector to group by keys and merge the values.

Example (Java 14 & above):

class Test {

	// sample data types
	record Sub ( int type, String value ){}
    record Clazz (String id, List&lt;Sub&gt; sub){}

	public static void main(String[] args)
	{
		// sample data
		List&lt;Clazz&gt; classes = List.of(
			new Clazz(&quot;id1&quot;,List.of(new Sub(1,&quot;A&quot;),new Sub(2,&quot;B&quot;))),
			new Clazz(&quot;id2&quot;,List.of(new Sub(3,&quot;C&quot;),new Sub(4,&quot;D&quot;))),
			new Clazz(&quot;id1&quot;,List.of(new Sub(5,&quot;E&quot;),new Sub(6,&quot;A&quot;)))
		);

		Map&lt;String, List&lt;String&gt;&gt; map = classes.stream()
			.collect(Collectors.toMap(
				// key for new map: c.id
				c -&gt; c.id,
				
				// value for new map: c.sub[].value as a list
				c -&gt; c.sub.stream().map(s -&gt; s.value).toList(),
				
				// duplicate value merging (grouping) : merge two value lists, no duplicates
				(v1, v2) -&gt; Stream.concat(v1.stream(), v2.stream()).distinct().toList()
			));

		// print resulting data
		map.forEach((k,v) -&gt; System.out.println(k + &quot;\t-&gt;\t&quot; + String.join(&quot;,&quot;, v)));
	}
}

Output:

id2	-&gt;	C,D
id1	-&gt;	A,B,E

答案2

得分: 0

就像@Sametcey建议的那样,您可以使用flatMap
每当遇到使用嵌套列表的情况(就像您的Map&lt;String,List&lt;List&gt;&gt;一样,但也可以在更深层次上使用,如Map&lt;String,List&lt;List&lt;List&gt;&gt;&gt;),flatMap会对此进行帮助。

它会将您的流转换为一个单一的扁平流。换句话说:一个可以访问和操作的列表。

英文:

Just like @Sametcey suggested you can use flatMap.<br> Whenever you encounter something that uses nested lists (just like your Map&lt;String, List&lt;List&gt;&gt;, but it's possible to use it on deeper level like Map&lt;String, List&lt;List&lt;List&gt;&gt;&gt;) flatMap will help you with that.

It will transform your stream into a single flattened stream. In other words: one list that you can access and manipulate.

huangapple
  • 本文由 发表于 2023年4月4日 15:25:38
  • 转载请务必保留本文链接:https://go.coder-hub.com/75926572.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定