What is the most elegant way to iterate over all super classes/interfaces of a given Class<?> object? I am basically looking for a recursive getSuperclass() and getInterfaces() method, collecting the whole class hierarchy.
Lets assume our inheritance looks like follows (where Cn are classes and In are interfaces):
I3
↗ ↖
C2 I1 I2
↖ ↖ ↗
C1 I0
↖ ↗
C0
It should catch all classes displayed above. If possible, the iteration order should be breadth first, so something like this:
C0 -> C1 -> I0 -> C2 -> I1 -> I2 -> I3
Is there a built in method or a library providing creating a Collection<Class<?>>, Stream<Class<?>> or an Iterator<Class<?>>?
Any help is appretiated.
Given that you already seem to use Guava, here's a solution using Guava's Graph Traversal utilities.
public static Iterable<Class<?>> getClassHierarchy(Class<?> baseClass) {
return Traverser.forGraph(
(SuccessorsFunction<Class<?>>) node -> {
Class<?> superclass = node.getSuperclass();
List<Class<?>> interfaces = Arrays.asList(node.getInterfaces());
return superclass == null ? interfaces
: Iterables.concat(interfaces, Collections.singleton(superclass));
}
).breadthFirst(baseClass);
}
This solution implements an Iterator<Class<?>>. If you are OK with using libraries, I would recommend checking out the accepted answer.
public static class HierarchyIterator implements Iterator<Class<?>> {
private Queue<Class<?>> remaining = new LinkedList<>();
private Set<Class<?>> visited = new LinkedHashSet<>();
public HierarchyIterator(Class<?> initial) {
append(initial);
}
private void append(Class<?> toAppend) {
if (toAppend != null && !visited.contains(toAppend)) {
remaining.add(toAppend);
visited.add(toAppend);
}
}
#Override
public boolean hasNext() {
return remaining.size() > 0;
}
#Override
public Class<?> next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Class<?> polled = remaining.poll();
append(polled.getSuperclass());
for (Class<?> superInterface : polled.getInterfaces()) {
append(superInterface);
}
return polled;
}
}
If you need a Collection<Class<?>>, you can use Google Guava for:
public static Set<Class<?>> getClassHierarchy(Class<?> forClass) {
Set<Class<?>> result = new LinkedHashSet<>();
Iterators.addAll(result, new HierarchyIterator(forClass));
return result;
}
calling:
System.out.println(getClassHierarchy(LinkedList.class));
yields
[class java.util.LinkedList, class java.util.AbstractSequentialList, interface java.util.List, interface java.util.Deque, interface java.lang.Cloneable, interface java.io.Serializable, class java.util.AbstractList, interface java.util.Collection, interface java.util.Queue, class java.util.AbstractCollection, interface java.lang.Iterable, class java.lang.Object]
I take your question more or less like a game, and I noticed that the breadth first requirement is not mandatory, so here is my solution.
It uses reflection.
It uses recursion.
It uses functional programming.
It is not very long.
It implements an internal iterator - forEach style.
You need Java 9 to compile it.
It is just a programming game :)
public class ClassIterator {
public void forEachSuperclasses(final Class<?> initialClass, final Consumer<Class<?>> action) {
generateStream(initialClass).distinct().forEach(action);
}
private Stream<Class<?>> generateStream(final Class<?> clazz) {
if (clazz == null) {
return Stream.empty();
}
return Stream.concat(
Stream.concat(Stream.of(clazz), generateStream(clazz.getSuperclass())),
Arrays.stream(clazz.getInterfaces()).flatMap(this::generateStream));
}
}
How to call it:
interface I3 {};
class C2 implements I3 {};
interface I1 extends I3 {};
interface I2 {};
class C1 extends C2 {};
interface I0 extends I0, I0 {};
class C0 extends C1 implements I0 {};
void testForEachSuperclasses() {
final ClassIterator iterator = new ClassIterator();
iterator.forEachSuperclasses(C1.class, System.out::println);
}
Output:
class com.example.classiterator.C0
class com.example.classiterator.C1
class com.example.classiterator.C2
class java.lang.Object
interface com.example.classiterator.I3
interface com.example.classiterator.I0
interface com.example.classiterator.I1
interface com.example.classiterator.I2
Here's another solution without external libraries, but which still works lazily and visits every class exactly once:
public static Iterable<Class<?>> getClassHierarchy(Class<?> baseClass) {
return () -> new Iterator<Class<?>>() {
private Class<?> nextValue;
private Queue<Class<?>> remaining = new LinkedList<>(Collections.singleton(baseClass));
private Set<Class<?>> visited = new HashSet<>();
#Override
public boolean hasNext() {
while (nextValue == null && !remaining.isEmpty()) {
Optional.ofNullable(remaining.poll())
.ifPresent((Class<?> type) -> {
visited.add(type);
Stream.concat(
streamOptional(Optional.ofNullable(type.getSuperclass())),
Arrays.stream(type.getInterfaces())
).filter(visited::add)
.forEach(remaining::offer);
nextValue = type;
});
}
return nextValue != null;
}
private <T> Stream<T> streamOptional(final Optional<T> optional) {
return optional.map(Stream::of).orElse(Stream.empty());
}
#Override
public Class<?> next() {
if (!hasNext()) {
throw new NoSuchElementException();
}
Class<?> value = this.nextValue;
this.nextValue = null;
return value;
}
};
}
Note: writing this was a pain (in Java 8), because unfortunately, there is no Optional.stream() method and Stream.generate(supplier) can't be terminated so I couldn't use it.
Here is a quick Breadth First Hierarchy transverse:
public class ClassHierarchy {
private Queue<Class<?>> queue;
//a collection of "visited" classes,
//which is also the result of the search
private Set<Class<?>> visited;
public Set<Class<?>> getClassHierarchy(Class<?> cls){
visited = new LinkedHashSet<>(); //initialize visited log
bfs(cls);
return visited;
}
//breadth first traverse on hierarchy
private void bfs(Class<?> cls) {
if(cls == null){ return; }
queue = new LinkedList<>(); //initialize queue
queue.add(cls);
while (! queue.isEmpty()) {
cls = queue.poll();
//loop over super classes
for(Class<?> nextClass : getSuperClasses(cls)){
if((nextClass != null) && visited.add(nextClass)) {
queue.add(nextClass); //add class to the queue
}
}
}
return;
}
private List<Class<?>> getSuperClasses(Class<?> cls) {
List<Class<?>> superCs = new ArrayList<>();
superCs.addAll(Arrays.asList(cls.getInterfaces()));
superCs.add(cls.getSuperclass());
return superCs;
}
private boolean isVisited(Class<?> cls) {
return !(visited.add(cls));
}
public static void main(String[] args) {
ClassHierarchy ch = new ClassHierarchy();
System.out.println(ch.getClassHierarchy(LinkedList.class));
}
}
(Please check carefully. I did not have time yet to debug and improve. Will look at it later)
Related
I have a custom implementation of a Predicate that I want to use in some operations.
However, I am having a hard type making polymorphism work with it.
After some investigation I wrote the minimal code below to reproduce the problem (which is a better explanation of the problem than I could describe).
class Custom implements Predicate<Integer> {
int y;
public Custom(int y) {
this.y = y;
}
#Override
public boolean test(Integer i) {
return y+i>0;
}
}
public class Main{
public static void main(String[] args) {
Custom c1 = new Custom(5);
Custom c2 = new Custom(8);
Custom c = (Custom) c1.and(c2); // faulty line - unable to cast
}
}
I am unsure why the casting fails and how to make it work.
If you want to preserve state of your Custom objects and implement the Predicate interface I would suggest to overload the and, or and negate methods. When you combine two Custom objects with and, or or when you call negate you will get a Custom object as return value. When you combine a Custom object with any other implementation of Predicate<Integer the methods will still return Predicate<Integer:
class Custom implements Predicate<Integer> {
class And extends Custom {
Custom a;
Custom b;
public And(Custom a, Custom b) {
super((i) -> a.test(i) && b.test(i));
this.a = a;
this.b = b;
}
}
class Or extends Custom {
Custom a;
Custom b;
public Or(Custom a, Custom b) {
super((i) -> a.test(i) || b.test(i));
this.a = a;
this.b = b;
}
}
class Not extends Custom {
Custom custom;
public Not(Custom custom) {
super((i) -> !custom.test(i));
this.custom = custom;
}
}
private final Predicate<Integer> predicate;
public Custom(int y) {
this((i) -> y + i > 0);
}
private Custom(Predicate<Integer> predicate) {
this.predicate = predicate;
}
#Override
public boolean test(Integer i) {
return predicate.test(i);
}
public Custom.And and(Custom other) {
return new Custom.And(this, other);
}
public Custom.Or or(Custom other) {
return new Custom.Or(this, other);
}
public Custom.Not negate() {
return new Custom.Not(this);
}
}
I don't see a good reason of creating such a type of predicate as it complicates your predicates. However, there are at least 3 different ways that come to my mind "changing" the predicate state.
v0 - simply use java.util.function.Predicate<T>
final Predicate<String> p1 = "foo"::equals;
final Predicate<String> unit1 = p1.or("bar"::equals);
Assertions.assertTrue(unit1.test("foo"));
Assertions.assertTrue(unit1.test("bar"));
Assertions.assertFalse(unit1.test("baz"));
final Predicate<String> unit2 = p1.or("baz"::equals);
Assertions.assertTrue(unit2.test("foo"));
Assertions.assertTrue(unit2.test("baz"));
There is nothing wrong with this code and I would still go with it not implementing any custom classes.
v1 - "do cast" in a custom predicate implementation
This still requires all default methods from the Predicate<T> interface to be overridden in order not to break in a future Java release.
public abstract class V1MutablePredicate<T, P extends V1MutablePredicate<T, P>>
implements Predicate<T> {
#Nullable
private final Predicate<T> predicate;
protected V1MutablePredicate(#Nullable final Predicate<T> predicate) {
this.predicate = predicate;
}
protected abstract boolean doTest(T t);
#Nonnull
protected abstract P wrap(#Nonnull Predicate<T> predicate);
#Override
public final boolean test(final T t) {
return predicate == null ? doTest(t) : predicate.test(t);
}
#Nonnull
#Override
public final P and(#Nonnull final Predicate<? super T> other) {
return wrap(Predicate.super.and(other));
}
#Nonnull
#Override
public final P negate() {
return wrap(Predicate.super.negate());
}
#Nonnull
#Override
public final P or(#Nonnull final Predicate<? super T> other) {
return wrap(Predicate.super.or(other));
}
}
private static final class Custom
extends V1MutablePredicate<String, Custom> {
private String s;
Custom(final String s) {
this(null, s);
}
private Custom(#Nullable final Predicate<String> predicate, final String s) {
super(predicate);
this.s = s;
}
#Override
protected boolean doTest(final String t) {
return t.equals(s);
}
#Nonnull
#Override
protected Custom wrap(#Nonnull final Predicate<String> predicate) {
return new Custom(predicate, s);
}
}
#Test
public void test() {
final Custom p1 = new Custom("foo");
final Custom p2 = new Custom("bar");
final Custom unit = p1.or(p2);
Assertions.assertTrue(unit.test("foo"));
Assertions.assertTrue(unit.test("bar"));
Assertions.assertFalse(unit.test("baz"));
p2.s = "baz";
Assertions.assertTrue(unit.test("foo"));
Assertions.assertTrue(unit.test("baz"));
}
This one seems to be closest to what you want to accomplish.
v2 - inject the predicate state from outside
public final class V2MutablePredicate<T, S>
implements Predicate<T> {
private final Supplier<? extends S> stateSupplier;
private final BiPredicate<? super S, ? super T> predicate;
public V2MutablePredicate(final Supplier<? extends S> stateSupplier, final BiPredicate<? super S, ? super T> predicate) {
this.stateSupplier = stateSupplier;
this.predicate = predicate;
}
#Override
public boolean test(final T t) {
return predicate.test(stateSupplier.get(), t);
}
}
final AtomicReference<String> r1 = new AtomicReference<>("foo");
final V2MutablePredicate<String, String> p1 = new V2MutablePredicate<>(r1::get, String::equals);
final AtomicReference<String> r2 = new AtomicReference<>("bar");
final V2MutablePredicate<String, String> p2 = new V2MutablePredicate<>(r2::get, String::equals);
final Predicate<String> unit = p1.or(p2);
Assertions.assertTrue(unit.test("foo"));
Assertions.assertTrue(unit.test("bar"));
Assertions.assertFalse(unit.test("baz"));
r2.set("baz");
Assertions.assertTrue(unit.test("foo"));
Assertions.assertTrue(unit.test("baz"));
This implementation requires the state to be changed from outside managing multiple objects to be handled and it also requires "state" classes, but it does not require the default methods to be overridden and also requires the supplier to provide the value in every test method call.
I wish to be able to get a List/ArrayList of N new instances from a static method inherited to subclasses so that I don't have to rewrite this same function in all subclasses.
I want to implement this so that I can build a vector containg some A and B. I've tried several methods but none of them worked for me :
public class Parent {
public static List<Parent> getNInstances(int n) {
List<Parent> out = new ArrayList<>();
for (int i = 0; i < n; i++) {
Parent newChildInstance = (Parent) MethodHandles
.lookup()
.lookupClass()
.getConstructor()
.newInstance()
out.add(newChildInstance);
}
}
}
I've got the MethodHandles thing from here since I feel like I need to get the class to be able to call .getConstructor().newInstance() which should, in theory, solve my problem. Nonetheless, this doesn't work, it gives me a NoSuchMethodException since he's not able to find the constructor from the Class given by
MethodHandles.lookup().lookupClass(), at least I think that's why.
Here is how I would like the method .getNInstances() to work.
public class Parent {
public Parent(){ }
public static List<Parent> getNInstances(int n) {
List<Parent> out = new ArrayList<>();
for (int i = 0; i < n; i++) {
Parent newChildInstance = ...
out.add(newChildInstance);
}
}
}
public class A extends Parent {
public A(){ }
}
public class B extends Parent {
public B(){ }
}
public class Main {
public static void main(String[] args) {
List<Parent> total = new ArrayList<>();
total.addAll(A.getNInstances(3));
total.addAll(B.getNInstances(4));
}
}
Here total should therefore be like [a, a, a, b, b, b, b] where a is an instance of A and b an instance of B, but by now, it's just empty.
There's no need at all to use reflection here. Use a factory and a method reference for the constructor.
This way you have compile-time assurance that the constructor you're trying to use actually exists.
abstract class ParentFactory
{
public List<Parent> getNInstances(int n)
{
final List<Parent> out = new ArrayList<>();
for (int i = 0; i < n; i++)
{
out.add(constructor().get());
}
return out;
}
protected abstract Supplier<Parent> constructor();
}
class AFactory extends ParentFactory
{
#Override
protected Supplier<Parent> constructor() {
return A::new;
}
}
class BFactory extends ParentFactory
{
#Override
protected Supplier<Parent> constructor() {
return B::new;
}
}
Sample usage:
List<Parent> total = new ArrayList<>();
total.addAll(new AFactory().getNInstances(3));
total.addAll(new BFactory().getNInstances(4));
I don't manage to reproduce your error.
But note some points :
1) Here, you will never lookup a class of the subclasses because lookupClass() returns the class that invoked the method and this is always Parent.getNInstances() :
Parent newChildInstance = (Parent) MethodHandles
.lookup()
.lookupClass()
.getConstructor()
.newInstance();
Make it an instance method will produce the same result.
2) Generic class should be enough to solve your problem and make it an instance method.
public class Parent<T extends Parent> {
public List<Parent> getNInstances(int n) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
List<Parent> out = new ArrayList<>();
for (int i = 0; i < n; i++) {
Class<T> clazz = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
Parent newChildInstance =
clazz.getConstructor().newInstance();
out.add(newChildInstance);
}
return out;
}
}
And subclasses :
public class A extends Parent<A> {
//...
}
public class B extends Parent<B> {
//...
}
Sample test :
List<Parent> total = new ArrayList<>();
total.addAll(new A().getNInstances(3));
total.addAll(new B().getNInstances(4));
System.out.println(total);
outputs :
[A#506e6d5e, A#96532d6, A#3796751b, B#67b64c45, B#4411d970,
B#6442b0a6, B#60f82f98]
Normally when you implement a generic, you have some type T that you want to generalize. I want to write a class that generalizes a HashSet<T>.
I'm trying to write this the following way, but it's not the correct syntax or maybe it's not supported:
public class PermutationHelper<T> implements Iterable<T> {
private HashSet<T> m_set;
private long numberOfPermutations;
private boolean includeEmptyPermutationAsOutput = false;
public PermutationHelper(HashSet<T> set) {
m_set = set;
numberOfPermutations = 2 ^ set.size();
}
public void setIncludeEmptyPermutationAsOutput(boolean value) {
includeEmptyPermutationAsOutput = value;
}
#Override
public Iterator<T> iterator() {
Iterator<T> it = new Iterator<T>() {
long currentIndex = (includeEmptyPermutationAsOutput ? 0 : 1);
#Override
public boolean hasNext() {
return currentIndex < numberOfPermutations;
}
#Override
public T next() {
HashSet<T> result = new HashSet<T>();
return result; // expects T, but is a HashSet<T>..
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
};
return it;
}
}
I want the Iterator to give me all subsets of the passed-in HashSet<T>.
You can easly do
public class PermutationHelper<T extends HashSet<T>> implements Iterable<T>
in order to 'force' the generic type to be an HashSet or a subtype of a HashSet
What you want is simply
public class PermutationHelper<T> implements Iterable<HashSet<T>>
Your class is generic. You choose to name its generic type T. And it implements Iterable<HashSet<T>>, which means it must have a method
public Iterator<HashSet<T>> iterator()
java.lang.Class.getInterfaces returns all directly implemented interfaces ie doesn't walk the class tree to get all interfaces of all parent types. eg For example the hierarchy
public interface A {}
public interface B {}
public interface C extends B {}
public class Foo implements A {} // Foo.class.getInterfaces() returns [A]
public class Bar implements C {} // Bar.class.getInterfaces() returns [C], note B is not included.
For Bar I would like to get [B, C], but for any arbitrary tree depth.
I could write this myself, but I'm sure a library must exist that does this already, any ideas?
Apache Commons Lang has method you need: ClassUtils.getAllInterfaces
Guava Solution:
final Set<TypeToken> tt = TypeToken.of(cls).getTypes().interfaces();
This is a much more powerful and cleaner reflection API than the ancient Apache stuff.
Don't forget, Spring Framework has many similar util classes like Apache Commons Lang. So there is: org.springframework.util.ClassUtils#getAllInterfaces
public interface A {}
public interface B {}
public interface E extends B{ }
public class C implements A{}
public class D extends C implements E{}
public class App {
public static void main(String[] args) {
final List<Class<?>> result = getAllInterfaces(D.class);
for (Class<?> clazz : result) {
System.out.println(clazz);
}
}
public static List<Class<?>> getAllInterfaces(Class<?> clazz) {
if (clazz == null) {
System.out.println(">>>>>>>>>> Log : null argument ");
return new ArrayList<>();
}
List<Class<?>> interfacesFound = new ArrayList<>();
getAllInterfaces(clazz, interfacesFound);
return interfacesFound;
}
private static void getAllInterfaces(Class<?> clazz,
List<Class<?>> interfacesFound) {
while (clazz != null) {
Class<?>[] interfaces = clazz.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
if (!interfacesFound.contains(interfaces[i])) {
interfacesFound.add(interfaces[i]);
getAllInterfaces(interfaces[i], interfacesFound);
}
}
clazz = clazz.getSuperclass();
}
}
}
I am trying to understand Java Iterator and Iterable interfaces
I am writing this class
class MyClass implements Iterable<String> {
public String[] a = null;
public MyClass(String[] arr) {
a = arr;
}
public MyClassIterator iterator() {
return new MyClassIterator(this);
}
public class MyClassIterator implements Iterator<String> {
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m) {
myclass = m;
}
public boolean hasNext() {
return count < myclass.a.length;
}
public String next() {
int t = count;
count++;
return myclass.a[t];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
}
It seems to be working.
Should I have:
Myclass implements Iterable<Stirng>, Iterator<String> {
}
Or I should put MyClassIterator outside MyClass as
class MyClass implements Iterable<String> {
public String[] a = null;
public MyClass(String[] arr) {
a = arr;
}
public MyClassIterator iterator() {
return new MyClassIterator(this);
}
}
public class MyClassIterator implements Iterator<String> {
private MyClass myclass = null;
private int count = 0;
public MyClassIterator(MyClass m) {
myclass = m;
}
public boolean hasNext() {
return count < myclass.a.length;
}
public String next() {
int t = count;
count++;
return myclass.a[t];
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Which one is better?
You should almost never implement both Iterable and Iterator in the same class. They do different things. An iterator is naturally stateful - as you iterate using it, it has to update its view of the world. An iterable, however, only needs to be able to create new iterators. In particular, you could have several iterators working over the same original iterable at the same time.
Your current approach is pretty much okay - there are aspects of the implementation I'd change, but it's fine in terms of the separation of responsibilities.
You were on track with your first try. MyClass only needs to implement Iterable<String>, which in turn requires you to provide an Iterator<String> implementation to return from Iterable<String>.iterator().
There's no need to put the MyClassIterator outside of MyClass because in most cases you will never even need to directly use the Iterator<String> (it's used implicitly by the for .. in .. syntax on Iterable<String>s), and in all other cases the interface is sufficient unless you actually add additional behavior to the implementation (which you likely won't ever need to do).
Here's how I'd do it, see comments inlined:
import java.util.Iterator;
class MyClass implements Iterable<String>{
public String[] a=null; //make this final if you can
public MyClass(String[] arr){
a=arr; //maybe you should copy this array, for fear of external modification
}
//the interface is sufficient here, the outside world doesn't need to know
//about your concrete implementation.
public Iterator<String> iterator(){
//no point implementing a whole class for something only used once
return new Iterator<String>() {
private int count=0;
//no need to have constructor which takes MyClass, (non-static) inner class has access to instance members
public boolean hasNext(){
//simplify
return count < a.length;
}
public String next(){
return a[count++]; //getting clever
}
public void remove(){
throw new UnsupportedOperationException();
}
};
}
}
You should not do Myclass implements Iterable<String>,Iterator<String>{ since iterators are single-use. With the exception of list iterators, there's no way to return them to the start.
Incidentally, you can skip the
MyClass myClass;
public MyClassInterator(MyClass m){
myclass=m;
}
and instead of referencing
myClass
reference
MyClass.this
Your inner class is not static, so MyClass.this will reference the instance of the enclosing class that created it.