在java8中对不同的对象流执行平面映射时,是否可以合并列表属性



我有一个流操作,它没有完全完成我想要的

给定这种数据结构

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);

最新更新