Java8 Streaming Class Hierarchy

I'm slowly learning the new features of Java 8, and I'm trying to find a way to handle the class hierarchy (from child to parent) as a stream.

For example, find annotation for a class or parents.

Prior to Java 8, I would do this as follows:

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;
}

Now I want to do this with more "functional programming." I could not find a better way than concatenating streams with recursive, as this happens:

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);
    }
}

But I am not completely satisfied with the decision. Although I did not compare this, I think that stream concatenation is rather cumbersome and in execution state.

Is there a better way to turn recursion into a stream?

+2
source share
1

Java 9 , ,

public static Stream<Class<?>> streamSuperclass(Class<?> type) {
    return Stream.iterate(type, Objects::nonNull, Class::getSuperclass);
}

Java 8 , Stream :

public static Stream<Class<?>> streamSuperclass(Class<?> type) {
    return StreamSupport.stream(
        new Spliterators.AbstractSpliterator<Class<?>>(100L,
            Spliterator.ORDERED|Spliterator.IMMUTABLE|Spliterator.NONNULL) {
            Class<?> current = type;
            public boolean tryAdvance(Consumer<? super Class<?>> action) {
                if(current == null) return false;
                action.accept(current);
                current = current.getSuperclass();
                return true;
            }
        }, false);
}

, java.lang.Object. , Object , , , , Stream.concat .

public static Stream<Class<?>> streamSuperclass(Class<?> type) {
    return reverse(Stream.<Class<?>>builder(), type, Class::getSuperclass).build();
}
private static <T> Stream.Builder<T> reverse(
        Stream.Builder<T> builder, T t, UnaryOperator<T> op) {
    return t==null? builder: reverse(builder, op.apply(t), op).add(t);
}

:

public static Stream<Class<?>> streamSuperclass(Class<?> type) {
    List<Class<?>> l=new ArrayList<>();
    for(; type!=null; type=type.getSuperclass()) l.add(type);
    Collections.reverse(l);
    return l.stream();
}

, , ArrayList , Stream.Builder, ...

+4

Source: https://habr.com/ru/post/1671132/


All Articles