如何通过使用Java流以最佳方式将List
当心:propertyA不是唯一的
//pseudo-code
class Foo
propertyA //not unique
List<propertyB>
到目前为止,我有以下内容:
fooList.stream()
.collect(Collectors.groupingBy(Foo::propertyA,
Collectors.mapping(Foo::propertyB, Collectors.toList())))
产生Map<propretyA, List<List<propretyB>>>
,但尚未对其值进行展平。
答案 0 :(得分:5)
您可以使用Java 9+ Collectors.flatMapping
:
Map<propretyA, List<propretyB>> result = fooList.stream()
.collect(Collectors.groupingBy(Foo::propertyA,
Collectors.flatMapping(foo -> foo.propertyB().stream(),
Collectors.toList())));
另一种方法(Java8 +)是使用this answer中的Collectors.toMap
。
Java8 +的另一种方法是不使用流,而是使用Map.computeIfAbsent
:
Map<propretyA, List<propretyB>> result = new LinkedHashMap<>();
fooList.forEach(foo -> result.computeIfAbsent(foo.propertyA(), k -> new ArrayList<>())
.addAll(foo.propertyB()));
答案 1 :(得分:4)
这应该做到:
fooList.stream()
.collect(Collectors.toMap(Foo::getPropertyA, Foo::getPropertyBList, (l1, l2) -> {
l1.addAll(l2);
return l1;
}));
答案 2 :(得分:1)
您可以将Collectors.toMap
与合并功能一起使用,在复制键时必须决定必须使用哪个List<propertyB>
:
Map<propertyA, List<propertyB>> collect = list.stream()
.collect(Collectors.toMap(Foo::getPropertyA, Foo::getList, (l1, l2) -> ???));
否则,您可以获得IllegalStateException
。来自javadoc:
如果映射的键包含重复项(根据Object.equals(Object)),则执行收集操作时将抛出IllegalStateException。
由您决定如何实现合并功能,但是通常您只想返回2个列表的并集,例如:l1.addAll(l2); return l1;