'Grouping a list of flat objects in a nested structure
I have a List of objects A, where the object A has this form:
Class A {
private String a1;
private String a2;
private String a3;
private String a4;
private String a5;
private String a6;
}
I need to group this List first by a1 and then by a3, resulting in this way:
Map<B, Map<C, List<D>>>, where the object B has this form
Class B {
private String a1;
private String a2;
}
and where the object C has this form
Class C {
private String a3;
private String a4;
}
and where the object D has this form
Class D {
private String a5;
private String a6;
}
Is this possibile with streams in Java 11? Any other ways to achieve this goal are welcome, thanks very much!
Solution 1:[1]
Suppose you have these lombok annotations on your classes (It's fine if you don't have lombok - you can just add these boilerplate to your classes if you don't have them already):
@Getter
class A {
private String a1;
private String a2;
private String a3;
private String a4;
private String a5;
private String a6;
}
@AllArgsConstructor
@EqualsAndHashCode(exclude = "a2")
class B {
private String a1;
private String a2;
}
@AllArgsConstructor
@EqualsAndHashCode(exclude = "a4")
class C {
private String a3;
private String a4;
}
@AllArgsConstructor
class D {
private String a5;
private String a6;
}
Note that it is important that B and C's equals and hashCode only depend on a1 and a3 respectively.
Then given List<A> aList, you can nest the groupingBy collectors like this, and at the very end, map each thing to a D.
var map = aList.stream().collect(
Collectors.groupingBy(
x -> new B(x.getA1(), x.getA2()),
Collectors.groupingBy(
x -> new C(x.getA3(), x.getA4()),
Collectors.mapping(
x -> new D(x.getA5(), x.getA6()),
Collectors.toList()
)
)
)
);
and map will be a Map<B, Map<C, List<D>>>.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Sweeper |
