简体   繁体   English

在java 8中对不同的对象流执行flatmap时是否可以合并列表属性?

[英]Is it possible to merge list properties while performing flatmap on different streams of objects in java 8?

I have a stream operation which is not quite doing what I want it to我有一个流操作,它并没有完全按照我的意愿行事

Given this data structure鉴于此数据结构

CatOwner {
    id, 
    name, 
    List <CatType>
}           

This code这段代码

    List<CatOwner> catOwner = owners.stream()
               .map(CatOwnerAccount:getCatOwnerAccountDetails)
               .filter(Objects::nonNull)
               .flatMap(catOwnerFunction)
               .distinct()
               .collect(Collectors.toList());

Where在哪里

Function<CatOwnerAccountDetails, Stream<CatOwner>> catOwnerFunction = catOwnerDetails -> getCatOwners(catOwnerDetails);

I would like this to give me a merged list of unique owners, combining all their cats from different sources, so rather than producing this (as it is flatmapping and then doing a distinct on objects wioth different lists) it would merge the lists我希望这能给我一个唯一所有者的合并列表,将他们所有来自不同来源的猫组合起来,所以与其生成这个(因为它是平面映射,然后在不同列表的对象上做一个不同的),它会合并列表

so instead of producing this所以而不是生产这个

{ 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] }

it would produce this它会产生这个

{ id : 1, name: Steve, cattype : [tabby, ginger, black] }
{ id : 2, name: Mandy, cattype : [tortashelle, manx, grey]  }

Can anyone help ?任何人都可以帮忙吗?

You can do so by creating an intermediate map, but it's not very pretty.你可以通过创建一个中间地图来做到这一点,但它不是很漂亮。

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

I used a javafx.util.Pair as the key, though any tuple class that implements equality as the combined equality of the two elements will do.我使用javafx.util.Pair作为键,尽管任何实现相等作为两个元素的组合相等的元组类都可以。

owner -> new Pair<>(owner.getId(), owner.getName())

This says that the values of the map are the CatOwner items themselves (that is, the map is Pair<Id, Name> to CatOwner ).这表示映射的值是CatOwner项本身(即映射是Pair<Id, Name>CatOwner )。

Function.identity()

This says that if there is an collision (two items with the same ID and name), the way to resolve that is to add all of the types from one CatOwner to the other.这表示如果发生冲突(具有相同 ID 和名称的两个项目),解决该问题的方法是将一个CatOwner所有类型添加到另一个CatOwner

(a, b) -> {
    a.getTypes().addAll(b.getTypes());
    return a;
}

The result is a Collection , since you take all of the values of the map.结果是一个Collection ,因为您获取了地图的所有值。 If you really want/need a list, you can add the values into a new list.如果您真的想要/需要一个列表,您可以将这些值添加到一个新列表中。

new ArrayList<>(values);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM