One option is to use Stream.iterate()
. You'll have to combine it with takeWhile
(introduced in Java 9) in order to make the Stream
finite.
public static Stream<Class<?>> streamOfAncestors(Class<?> klass) {
return Stream.iterate (klass.getSuperclass(), k -> k != null ? k.getSuperclass() : null)
.takeWhile(Objects::nonNull);
}
Or, if you don't want to use Java 9 features, you can write a method similar to Stream.iterate()
, but make it produce a finite Stream
:
public static Stream<Class<?>> streamOfAncestors(Class<?> klass) {
final Iterator<Class<?>> iterator = new Iterator<Class<?>>() {
@SuppressWarnings("unchecked")
Class<?> k = klass.getSuperclass ();
@Override
public boolean hasNext() {
return k != null;
}
@Override
public Class<?> next() {
Class<?> curr = k;
k = k.getSuperclass ();
return curr;
}
};
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
iterator,
Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
}
Sample execution of the second method:
streamOfAncestors (StringBuilder.class).forEach (System.out::println);
Output:
class java.lang.AbstractStringBuilder
class java.lang.Object
EDIT:
As Holger commented, all of this is not necessary if you are using Java 9, which has a Stream.iterate variant that produces a finite Stream
.
All you need to write is:
public static Stream<Class<?>> streamOfAncestors(Class<?> klass) {
return Stream.iterate (klass.getSuperclass(), Objects::nonNull, Class::getSuperclass);
}