我有一个流操作,它没有完全完成我想要的
给定这种数据结构
CatOwner {
id,
name,
List <CatType>
}
此代码
List<CatOwner> catOwner = owners.stream()
.map(CatOwnerAccount:getCatOwnerAccountDetails)
.filter(Objects::nonNull)
.flatMap(catOwnerFunction)
.distinct()
.collect(Collectors.toList());
何处
Function<CatOwnerAccountDetails, Stream<CatOwner>> catOwnerFunction = catOwnerDetails -> getCatOwners(catOwnerDetails);
我希望这能给我一个独特主人的合并列表,将他们来自不同来源的所有猫合并在一起,所以它不会产生这个(因为它是平面映射,然后在不同列表的对象上进行不同的映射(,而是会合并列表
所以不是生产这种
{ id : 1, name: Steve, cattype : [tabby, ginger] }
{ id : 1, name: Steve, cattype : [black] }
{ id : 2, name: Mandy, cattype : [tortashelle] }
{ id : 2, name: Mandy, cattype : [manx, grey] }
它会产生这种
{ id : 1, name: Steve, cattype : [tabby, ginger, black] }
{ id : 2, name: Mandy, cattype : [tortashelle, manx, grey] }
有人能帮忙吗?
您可以通过创建一个中间映射来实现,但它不是很漂亮。
Collection<CatOwner> values = owners.stream()
// blah blah, the other stuff you had
.collect(
Collectors.toMap(
owner -> new Pair<>(owner.getId(), owner.getName()),
Function.identity(),
(a, b) -> {
a.getTypes().addAll(b.getTypes());
return a;
}
)
)
.values();
我使用了一个javafx.util.Pair
作为键,尽管任何将等式实现为两个元素的组合等式的元组类都可以
owner -> new Pair<>(owner.getId(), owner.getName())
这意味着映射的值是CatOwner
项本身(也就是说,映射是Pair<Id, Name>
到CatOwner
(。
Function.identity()
这意味着,如果发生冲突(两个项目具有相同的ID和名称(,解决方法是将所有类型从一个CatOwner
添加到另一个。
(a, b) -> {
a.getTypes().addAll(b.getTypes());
return a;
}
结果是Collection
,因为您获取了映射的所有值。如果你真的想要/需要一个列表,你可以将这些值添加到一个新的列表中。
new ArrayList<>(values);