包含唯一 sub-objects 的唯一 objects 列表

List of unique objects containing unique sub-objects

我正在尝试获取唯一 object 的列表,其中每个 object 还包含唯一 sub-objects 的列表。以下示例中的唯一性由每个 class.

中的 id 字段确定
public class MyMain {
    public static void main(String[] args) {
        Parent p1 = new Parent(1L);
        Child c11 = new Child(11L);
        Child c12 = new Child(12L);

        Parent p2 = new Parent(2L);
        Child c21 = new Child(21L);
        Child c22 = new Child(22L);
        Child c23 = new Child(23L);

        Holder holder1 = new Holder(p1.getId(), c11.getId());
        Holder holder2 = new Holder(p1.getId(), c11.getId());
        Holder holder3 = new Holder(p1.getId(), c11.getId());
        Holder holder4 = new Holder(p1.getId(), c11.getId());
        Holder holder5 = new Holder(p1.getId(), c12.getId());
        Holder holder6 = new Holder(p1.getId(), c12.getId());
        Holder holder7 = new Holder(p1.getId(), c12.getId());

        Holder holder8 = new Holder(p2.getId(), c21.getId());
        Holder holder9 = new Holder(p2.getId(), c21.getId());
        Holder holder10 = new Holder(p2.getId(), c21.getId());
        Holder holder11 = new Holder(p2.getId(), c22.getId());
        Holder holder12 = new Holder(p2.getId(), c23.getId());
        Holder holder13 = new Holder(p2.getId(), c23.getId());

        List<Holder> holders = new ArrayList<>();
        holders.add(holder1); holders.add(holder2); holders.add(holder3); holders.add(holder4);
        holders.add(holder5); holders.add(holder6); holders.add(holder7); holders.add(holder8);
        holders.add(holder9); holders.add(holder10); holders.add(holder11); holders.add(holder12); holders.add(holder13);
    }
}

@Value
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
class Parent {
    @EqualsAndHashCode.Include
    public Long id;
    public List<Child> chidren;

    public Parent(Long id) { this.id = id; }
}

@Value
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
class Child {
    @EqualsAndHashCode.Include
    public Long id;

    public Child(Long id) { this.id = id; }
}

@Value
class Holder {
    Long parentId;
    Long childId;

    public Holder(Long parentId, Long childId) {
        this.parentId = parentId;
        this.childId = childId;
    }
}

从上面的代码片段中,我希望得到一个 List<Parent>(来自 holders ),它将包含两个 parent:p1p2.然后每个 parent 将有一个 List<Child>,其中包含 parent 的唯一 children。

预期输出:

List<Parent> will have p1 and p2
p1.List<Child> will have c11 and c12 (only 2 entries)
p2.List<Child> will have c21, c22, c23 (only 3 entries)

我已经弄清楚如何获得唯一 parent 列表,但不确定如何获得唯一 children。

更新:

以下似乎对我有用,但是不确定是否有更好的方法。

public class MyMain {
    public static void main(String[] args) {
        MyMain m = new MyMain();
        Parent p1 = new Parent(1L, null);
        Child c11 = new Child(11L);
        Child c12 = new Child(12L);

        Parent p2 = new Parent(2L, null);
        Child c21 = new Child(21L);
        Child c22 = new Child(22L);
        Child c23 = new Child(23L);

        Holder holder1 = new Holder(p1.getId(), c11.getId());
        Holder holder2 = new Holder(p1.getId(), c11.getId());
        Holder holder3 = new Holder(p1.getId(), c11.getId());
        Holder holder4 = new Holder(p1.getId(), c11.getId());
        Holder holder5 = new Holder(p1.getId(), c12.getId());
        Holder holder6 = new Holder(p1.getId(), c12.getId());
        Holder holder7 = new Holder(p1.getId(), c12.getId());

        Holder holder8 = new Holder(p2.getId(), c21.getId());
        Holder holder9 = new Holder(p2.getId(), c21.getId());
        Holder holder10 = new Holder(p2.getId(), c21.getId());
        Holder holder11 = new Holder(p2.getId(), c22.getId());
        Holder holder12 = new Holder(p2.getId(), c23.getId());
        Holder holder13 = new Holder(p2.getId(), c23.getId());

        List<Holder> holders = new ArrayList<>();
        holders.add(holder1); holders.add(holder2); holders.add(holder3); holders.add(holder4);
        holders.add(holder5); holders.add(holder6); holders.add(holder7); holders.add(holder8);
        holders.add(holder9); holders.add(holder10); holders.add(holder11); holders.add(holder12); holders.add(holder13);

        Map<Long, Set<Long>> returnSet= holders.stream()
                .collect(Collectors.toMap(Holder::getParentId, x -> m.uniqChildIdSet(x), MyMain::merge));

        System.out.println(returnSet);
    }

    public static Set<Long> uniqChildIdSet(Holder holder) {
        HashSet<Long> uniqChild = new HashSet();
        uniqChild.add(holder.getChildId());
        return uniqChild;
    }

    public static Set<Long> merge(Set<Long> l1, Set<Long> l2) {
        l1.addAll(l2);
        return l1;
    }
}

@Value
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
class Parent {
    @EqualsAndHashCode.Include
    public Long id;
    public List<Child> chidren;

    public Parent(Long id, List<Child> chidren) { this.id = id;
        this.chidren = chidren;
    }
}

@Value
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
class Child {
    @EqualsAndHashCode.Include
    public Long id;

    public Child(Long id) { this.id = id; }
}

@Value
class Holder {
    Long parentId;
    Long childId;

    public Holder(Long parentId, Long childId) {
        this.parentId = parentId;
        this.childId = childId;
    }
}

这是您可以使用的,没有任何辅助方法。

它基本上做的是下面的事情

  1. Holder 的父 ID
  2. 分组
  3. 为此 Holder,获取所有 childId 属性并将它们放入 Set<Long>
Map<Long, Set<Long>> returnSet =  holders.stream()
                                         .collect(Collectors.groupingBy(
                                                      Holder::getParentId, 
                                                      Collectors.mapping(
                                                          Holder::getChildId, 
                                                          Collectors.toSet()
                                                      )
                                                  )
                                              );

输出

{1=[11, 12], 2=[21, 22, 23]}