mardi 25 octobre 2016

Java8 Streaming a class hierarchy

I am slowly learning the new Java 8 features and I am trying to find a way to process a class hierarchy (from child to parent) as a stream.

For instance find an annotation on a class or it's parents.

Before Java 8, I would have done it this way :

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 wish to do it with a more "functional programming" way. I could not find a better way than concatenate streams with a recursive like follow :

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 quite satisfied of the solution. Although I did not benchmark it I think the stream concatenation is quite cumbersome and under performant.

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





Aucun commentaire:

Enregistrer un commentaire