Я медленно изучаю новые функции Java 8, и я пытаюсь найти способ обработки иерархии классов (от дочернего к родительскому) в виде потока.Java8 Потоковая передача иерархии классов
Например, найдите аннотацию к классу или его родителям.
Перед Java 8, я бы сделал это так:
public static <T extends Annotation> T getAnnonationOn(Class<?> type, Class<T> annType) {
Class<?> t = type;
T annot = null;
while (t != null && annot == null) {
annot = t.getAnnotation(annType);
t = t.getSuperclass();
}
return annot;
}
Теперь я хочу сделать это с более «функционального программирования» способом. я не мог найти лучший способ, чем сцепить потоки с рекурсивным как следующим образом:
import java.lang.annotation.Annotation;
import java.util.stream.Stream;
public static <T extends Annotation> T getAnnonationOn(Class<?> type, Class<T> annType) {
return ClassIterator.streamSuperclass(type)
.map(t -> t.getAnnotation(annType))
.filter(a -> a != null)
.findFirst()
.orElse(null);
}
public static class ClassIterator {
public static Stream<Class<?>> streamSuperclass(Class<?> type) {
if (type.getSuperclass() != null) {
return Stream.concat(Stream.of(type), Stream.of(type.getSuperclass()).flatMap(ClassIterator::streamSuperclass));
}
return Stream.of(type);
}
}
Но я не вполне удовлетворен решением. Хотя я не сравнивал это, я думаю, что потоковая конкатенация довольно громоздка и исполнена.
Есть ли лучший способ превратить рекурсию в поток?
По сути, вы ищете 'takeWhile' (перебираете суперклассы и берете, пока это не пусто), см. http: // stackoverflow. ком/вопросы/20746429/предел-а-поток -by-a-predicate – Tunaki
'takeWhile()', входящий в Java 9. Также 3-arg версия 'Stream.iterate()', которая может моделировать циклы 'for'. –