java - 是否可以在 java 8 中的不同对象流上执行平面映射时合并列表属性?
问题描述
我有一个流操作并没有完全按照我的意愿去做
鉴于这种数据结构
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();
我使用 ajavafx.util.Pair
作为键,尽管任何实现相等作为两个元素的组合相等的元组类都可以。
owner -> new Pair<>(owner.getId(), owner.getName())
这表示地图的值是CatOwner
项目本身(即地图是Pair<Id, Name>
to CatOwner
)。
Function.identity()
这表示如果发生冲突(具有相同 ID 和名称的两个项目),解决该问题的方法是将所有类型从一个添加CatOwner
到另一个。
(a, b) -> {
a.getTypes().addAll(b.getTypes());
return a;
}
结果是 a Collection
,因为您获取了地图的所有值。如果您真的想要/需要一个列表,您可以将这些值添加到一个新列表中。
new ArrayList<>(values);