首页 > 解决方案 > 组合/合并列表中的对象成员

问题描述

我从列表中获得了 A 类的对象列表。其中一些对象在 id 和 name 中是相等的,但在列表 <B> 中不相等,并且列表 b 总是不同的。

我需要合并这些,以便我的列表仅由具有相同名称和 id 的对象 a 组成,并且收集来自同一组的所有 b 我可以使用 jdk 8 plus utils 所以流可以在这里使用.. 虽然我认为这里的反射更有用?

PS:我无法更改 b 类的 a 的内容,因为它们是生成的类并且没有访问/扩展的可能性

    @Test
    public void test() {
        List.of(new A(1, "a1", List.of(new B(1, "1b"))),
                new A(1, "a1", List.of(new B(2, "2b"))),
                new A(2, "a2", List.of(new B(3, "3b"))));
//expected
        List.of(new A(1, "a1", List.of(new B(1, "1b"), new B(2, "2b"))),
                new A(2, "a2", List.of(new B(3, "3b"))));


    }


    class A {
        public A(int id, String name, List<B> listB) {
            this.id = id;
            this.name = name;
            this.listB = listB;
        }
        int id;
        String name;
        List<B> listB;
    }

    class B {
        public B(int id, String name) {
            this.id = id;
            this.name = name;
        }
        int id;
        String name;
    }

标签: javajava-11

解决方案


如果您需要为每个id可以编写的实例保留一个实例(我假设对象具有 getter 和 setter)

System.out.println(xs.stream()
        .collect(groupingBy(A::getId, toList()))
        .values().stream()
        .peek(g -> g.get(0).setListB(
                g.stream()
                        .flatMap(h -> h.getListB().stream())
                        .collect(groupingBy(B::getId, toList()))
                        .values().stream()
                        .map(i -> i.get(0))
                        .collect(toList())))
        .map(g -> g.get(0))
        .collect(toList()));

您的输入案例与输出

[A(id=1, name=a1, listB=[B(id=1, name=b1), B(id=2, name=b2)]), A(id=2, name=a2, listB=[B(id=3, name=b3)])]

如果您可以创建新实例,那么您可以重新规范化列表

System.out.println(xs.stream()
        .flatMap(a -> a.getListB().stream().map(b -> List.<Object>of(a.id, a.name, b.id, b.name)))
        .distinct()
        .collect(groupingBy(o -> o.get(0), toList()))
        .values()
        .stream()
        .map(zs -> new A((int) zs.get(0).get(0), (String) zs.get(0).get(1),
                zs.stream().map(z -> new B((int) z.get(2), (String) z.get(3))).collect(toList())))
        .collect(toList()));

.get(0).get(0)(你可以使用一些中间类来改变丑陋的东西DenormalizedRow


推荐阅读