Java 8中的Streams groupingBy收集器

6

我该如何使用Java 8 API获取这个数据结构?

这是我的对象结构:

class A {

    B b;

    public A(B b) {
        this.b = b;
    }
}

class B {

    List<A> as;

    private int i;

    public B(int i) {
        this.i = i;
    }
}

我正在尝试将它聚合到一起

 Map<A, List<B>> bs;

来自

List<A> as = new ArrayList<>();
as.add(a1);
as.add(a2);
as.add(a3);

1
as.stream().collect(groupingBy(a -> a.b)) - 为了使用方法引用,最好在 A 中添加一个 b 的 getter。您还需要在 B 上实现 equalshashCode 方法,以便正确运行。 - Boris the Spider
2个回答

7

使用 groupingBy:

Map<B, List<A>> bs = as.stream().collect(Collectors.groupingBy(A::getB));

假设类 A 拥有 getB() 方法。

除非 B 有一个未显示的秘密 equalshashCode,并且 A 有一个未显示的秘密 getB,否则这将不会做任何事情。 - Boris the Spider
@BoristheSpider 是的,让 B 覆盖 equalshashCode 是有意义的,但即使它没有覆盖,它仍然会通过 equalshashCode 的默认实现执行分组(例如,在 OP 的示例代码中,两个 A 实例共享同一个 B 实例,因此它们将被分组在一起)。 - Eran
@Bharath 为什么你需要一个 Map<A, List<B>> bs?每个 A 实例不是只有一个 B 实例吗? - Eran
@Bharath 如果 A 引用了一个单独的 B 实例,那么如何让多个 B 与同一个 A 相关联呢? - Eran
我同意。我的问题有点错了。:(。不过还是谢谢。我试图模仿一个Hibernate实体,但忘记在B上添加OneToMany关系。 - Bharath

7

实际上这很简单(假设B中存在hashCode/equals

as.stream()
  .collect(Collectors.groupingBy(A::getB))

1
@BoristheSpider,没错,我提到了第一个,第二个只是猜测。 - Eugene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接