I have a list of super classes (List<SuperClass> classes = ...
) that I want to split into separate lists based on their subtypes. I want to end up with lists parameterized with the subtype, i.e. List<A> aClasses = ...
not List<SuperClass> aClasses = ...
Given this class hierarchy:
abstract class SuperClass {...}
class A extends SuperClass {...}
class B extends SuperClass {...}
class C extends SuperClass {...}
Here's what I have so far, which does work. The issue is that when iterating over the aClasses
, bClasses
, and cClasses
lists, I need to cast the object inside the loop.
List<SuperClass> classes = ... // mix of A, B, and C
Map<Class<? extends SuperClass>, List<SuperClass>> grouped = classes.stream()
.collect(Collectors.groupingBy(SuperClass::getClass, Collectors.toList()));
List<SuperClass> aClasses = grouped.get(A.class);
List<SuperClass> bClasses = grouped.get(B.class);
List<SuperClass> cClasses = grouped.get(C.class);
I know this works, but I'm looking for more succinct code (probably using streams). Although after writing out the code below, I'm thinking anything more I can do with streams will probably be just about as "complicated" as the code below.
List<A> aClasses = new ArrayList<A>();
List<B> bClasses = new ArrayList<B>();
List<C> cClasses = new ArrayList<C>();
for (SuperClass superClass : classes) {
if (superClass instanceof A) {
aClasses.add(superClass);
}
else if (superClass instanceof B) {
bClasses.add(superClass);
}
else if (superClass instanceof C) {
cClasses.add(superClass);
}
}
The resulting classes will be inputs into methods with these signatures:
void processA(List<A> aClasses);
void processB(List<B> bClasses);
void processC(List<C> cClasses);
And I'm not going to do this: processA((List<A>) (List) aClasses);