Java 8 Stream“收集并分组”映射到多个键的对象 [英] Java 8 Stream "collect and group by" objects that map to multiple keys

查看:628
本文介绍了Java 8 Stream“收集并分组”映射到多个键的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下对象:

public class Item {
    String value;
    List<Person> owners;
    Person creator;
}

public class Person {
    String name;
    int id;
    Person manager;
}

现在我有一个包含3个Item对象的列表:

now i have the a list containing 3 Item objects:

i1 -> {value="1", owners=[p1, p2, p3], creator=p4}
i2 -> {value="2", owners=[p2, p3], creator=p5}
i3 -> {value="3", owners=[p5], creator=p1}

Person对象是如下:

the Person objects are as follows:

p1 -> {manager=m1, ...}
p2 -> {manager=m2, ...}
p3 -> {manager=m3, ...}
p4 -> {manager=m2, ...}
p5 -> {manager=m1, ...}

我想根据经理对Item对象的流进行分组所有者和创作者。结果 Map< Person,List< Item>> 应如下所示:

I want to group the stream of Item objects based on managers of the owners and creator. The result Map<Person, List<Item>> should look like:

{
  m1: [i1, i2, i3],
  m2: [i1, i2],
  m3: [i1, i2]
}

我认为使用Stream和Collector API,我可以制作从Item到经理的地图, Map< ;项目,列表< Person>> 首先,然后反转映射。但有没有办法只使用Stream和Collectors进行我想要的映射?

I think using Stream and Collector APIs, I can make the map from Item to managers, Map<Item, List<Person>> first, then reverse the mapping. But is there any way to make the mapping I want using Stream and Collectors only?

推荐答案

我认为,这只能用于中间配对值,用于记住人员/经理与原始项目之间的关联。如果没有Java标准API中的标准对类型,我们必须求助于 Map.Entry ,它最接近 Pair 键入:

I think, this is only possible with an intermediate "pair" value to remember the association between a person/manager and the originating item. In absence of a standard pair type in Java’s standard API, we have to resort to Map.Entry which comes closest to a Pair type:

Map<Person, List<Item>> map = list.stream()
  .flatMap(item->item.getOwners().stream()
    .map(p->new AbstractMap.SimpleEntry<>(p.getManager(), item)))
  .collect(Collectors.groupingBy(Map.Entry::getKey,
    Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

使用 import static 改进后我们得到

Map<Person, List<Item>> map = list.stream()
  .flatMap(item->item.getOwners().stream().map(p->new SimpleEntry<>(p.getManager(), item)))
  .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, toList())));

结果

m1: [i1,i3]
m3: [i1,i2]
m2: [i1,i2]

不同,因为首先,标准地图没有明确的排序,其次,我认为你的预期错误为 m1 与示例数据中的 i2 无关。

which differs because first, the standard map has no defined ordering, second, I think you made a mistake regarding you expectation as m1 is not associated with i2 in your example data.

这篇关于Java 8 Stream“收集并分组”映射到多个键的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆