[英]Java 8 groupingBy for a list of Maps
I have a list of map for which i want to group them by name我有一个地图列表,我想按名称对其进行分组
List<Map> allObjs = new ArrayList<Map>();
Map<String, Object> src = new HashMap();
src.put("name", "asset1");
src.put("description", "desc1" );
src.put("definition", "def1" );
Map<String, Object> src2 = new HashMap();
src2.put("name", "asset1");
src2.put("description", "desc2" );
src2.put("definition", "def2" );
allObjs.add(src);
allObjs.add(src2);
I tried grouping them by我尝试将它们分组
Map<Object, List<Map>> result = allObjs.stream().collect(Collectors.groupingBy(p -> p.get("name")));
What i want is我想要的是
{
name=asset1,
description=["desc1","desc2"],
definition=["def1","def2"]
}
I want all the other keys to be grouped in a list But what i got is我希望将所有其他键分组在一个列表中但我得到的是
{asset1=[
{name=asset1, description=desc1, definition=def2},
{name=asset1, description=desc2, definition=def2}
]
}
How do i group all the other keys except name to a list like expected above?我如何将除 name 之外的所有其他键分组到上面预期的列表中?
You can use groupBy
with mapping
to get the desired result, just values would be of single type only,您可以使用
groupBy
和mapping
来获得所需的结果,只是值只能是单一类型,
Map<String, Set<String>> collect1 = allObjs.stream()
.flatMap(m -> m.entrySet().stream())
.collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toSet())));
Result:结果:
{
name=[asset1],
description=[desc1,desc2],
definition=[def1,def2]
}
groupingBy
will group the items based on a key. groupingBy
将根据键对项目进行groupingBy
。 It does not do a merge of two maps.它不会合并两个地图。 This is one of the ugly ways to achieve what you want.
这是实现您想要的丑陋方法之一。
Given给定的
List<Map<String, String>> allObjs = new ArrayList<>();
Map<String, String> src = new HashMap();
src.put("name", "asset1");
src.put("description", "desc1" );
src.put("definition", "def1" );
Map<String, String> src2 = new HashMap();
src2.put("name", "asset1");
src2.put("description", "desc2" );
src2.put("definition", "def2" );
allObjs.add(src);
allObjs.add(src2);
One way to do is this.一种方法是这样做。 Create two classes, representing existing structure and final output structure
创建两个类,代表现有结构和最终输出结构
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class SomeClass {
private String name;
private String description;
private String definition;
}
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class NewClass {
private String name;
private List<String> description;
private List<String> definition;
}
Then this code should get the output u desired然后这段代码应该得到你想要的输出
final List<NewClass> collect = allObjs.stream()
.map(entry -> new SomeClass(entry.get("name"), entry.get("description"), entry.get("definition")))
.collect(Collectors.toList())
.stream()
.collect(Collectors.groupingBy(SomeClass::getName))
.entrySet()
.stream()
.map(entry -> {
final List<String> descriptions = entry.getValue().stream().map(SomeClass::getDescription).collect(Collectors.toList());
final List<String> definitions = entry.getValue().stream().map(SomeClass::getDefinition).collect(Collectors.toList());
return new NewClass(entry.getKey(), descriptions, definitions);
}).collect(Collectors.toList());
End result will be a list of type NewClass .最终结果将是 NewClass 类型的列表。 Each entry in the list will have the desired output with a unique key.
列表中的每个条目都将具有所需的输出和唯一的键。 You need to incorporate a lot of null checks since it is a Map we are dealing with.
您需要合并很多空检查,因为它是我们正在处理的 Map。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.