algorithmfoundry / Foundry

The Cognitive Foundry is an open-source Java library for building intelligent systems using machine learning

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

More permissive generics on ClusterCreators

Zero3 opened this issue · comments

The generics on the various ClusterCreators could perhaps be slightly more permissive. I'm using the standard Java convention of referencing stuff by the highest superinterface that makes sense in the context. For example:

List<String> list = new ArrayList<>();

Similarly, I intend to do:

ClusterCreator<Cluster<Vector>, Vector> creator = new DefaultClusterCreator<>();

However, this is not allowed because of the generics of DefaultClusterCreator. Instead, I have to do this:

ClusterCreator<? extends Cluster<Vector>, Vector> creator = new DefaultClusterCreator<>();

Could this be fixed? Of course there might be a good reason for this limitation. If so, please feel free to ignore this request :).

I think this is just a limitation in the Java generics that makes it need to enforce this way. The classes in the Foundry like ClusterCreator tend to specify exactly what type they're returning so that the full output can be inspected or even modified by callers. Thus, the DefaultClusterCreator creates a DefaultCluster, so that is what its generic specifies. That is why if you only want to deal with the super-level interface like Cluster, you need the ? extends Cluster<Vector>. But you could also just write:

ClusterCreator<DefaultCluster<Vector>, Vector> creator = new DefaultClusterCreator<>();

Are you trying to do something else with them that needs the generic to be the other way?

You are right. I found a relevant explanation in the Java tutorials here: https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html. Their example:

Although Integer is a subtype of Number, List<Integer> is not a subtype of List<Number> and, in fact, these two types are not related. The common parent of List<Number> and List<Integer> is List<?>.

Given this is how generics work, I don't think there is anything to change in how you do it at the moment. I'll close this issue again :).