Reputation: 403
I am trying to get a list of unique objects where each object further contains a list of unique sub-objects. Uniqueness in below example is determined by the id
field in each class.
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;
}
}
From the code fragment above, I am looking to get a List<Parent>
(from holders
) that will contain two parents: p1
and p2
. Each parent will then have a List<Child>
containing unique children for that parent.
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)
I have worked out how to get a list of unique parents but not sure how to achieve unique children as well.
Below seems to be working for me, however, not sure if there's a better way.
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;
}
}
Upvotes: 0
Views: 164
Reputation: 21995
Here is what you could use, without any helper methods.
What it's basically doing is the following
Holder
's parent idHolder
, take all the childId
properties and put them in a 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]}
Upvotes: 1