Существует подход для этого с чистым Stream
, рекурсивным просмотром класса до корневого класса Baz , а с groupingBy
мы можем получить Class
stats распределения , пример:
public static Map<Class, Long> foo(Collection<? extends Baz> messages) {
return messages.stream()
.map(Object::getClass)
.distinct()
.flatMap(i -> getParentClazzs(i, Baz.class))
.filter(i -> !Objects.equals(i, Baz.class))
.collect(
Collectors.groupingBy(Function.identity(), Collectors.counting())
);
}
private static Stream<Class> getParentClazzs(Class clazz, Class<Baz> rootClass) {
if (Objects.equals(clazz, rootClass)) {
return Stream.of(clazz);
}
return Stream.concat(Stream.of(clazz), getParentClazzs(clazz.getSuperclass(), rootClass));
}
foo(Arrays.asList(new Bar(), new Foo(), new Bar(), new C(), new D()))
.entrySet().stream()
.forEach(i -> System.out.println(i.getKey().getSimpleName() + " " + i.getValue()));
Выход:
C -> Бар -> Баз
D -> Бар -> Баз
Foo -> Баз
C 1
D 1
Foo 1
Бар 3