Question & Explanation
Is there a way in Java to hand over HashSet<Class>
arguments to a method so that the method will accept HashSets of subclasses of Class
?
This would be useful if there are several subclasses of a class the differences of which are not relevant to the method in question. If this is not possible, the only options to handle this seem to be
- to write as many methods as there are subclasses
- to loop through the HashSet in the calling function and call a similar method with the individual class instances as argument instead of the HashSets
... both are not very practical.
The version is Java 8 (openjdk 1.8.0).
Example
All files are assumed to be in the same directory so that we do not have to worry about packages and files importing each other. Consider a classes NNB and a subclass NNC (subclass of NNB).
NNB.java
:
import java.util.HashMap;
import java.util.Map;
public class NNB {
public final Map<Long, Double> dict;
public NNB () {
this.dict = new HashMap<Long, Double>();
int c = 0;
while (c<10) {
Long XX = (long)10;
Double YY = 2.0;
this.dict.merge(XX, YY, Double::sum);
System.out.println(dict);
c++;
}
}
}
NNC.java
:
import java.util.HashMap;
import java.util.Map;
public class NNC extends NNB {
private Map<Long, Double> dict2;
public NNC () {
super();
this.dict2 = new HashMap<Long, Double>();
}
}
Now assume, we want to call a method over a list of instances of NNB and NNC (say, to print NNB.dict
and NNC.dict
).
This does not work: NNA2.java
:
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
public class NNA2 {
public void printDict(HashSet<NNB> nnbs) {
for (NNB nnb : nnbs) {
System.out.println(nnb.dict);
}
}
public static void main(String args[]) {
NNA2 inst = new NNA2();
HashSet<NNB> x = new HashSet<NNB>(Arrays.asList(new NNB()));
HashSet<NNC> y = new HashSet<NNC>(Arrays.asList(new NNC()));
inst.printDict(x);
inst.printDict(y); //here it fails
System.exit(0);
}
}
Error:
NNA2.java:26: error: incompatible types: HashSet<NNC> cannot be converted to HashSet<NNB>
inst.printDict(y);
This works (but is not quite what we wanted and would be unpractical if we wanted to perform more complex operations): NNA1.java
:
import java.util.HashSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Arrays;
public class NNA1 {
public void printOneDict(NNB nnb) {
System.out.println(nnb.dict);
}
public static void main(String args[]) {
NNA1 inst = new NNA1();
HashSet<NNB> x = new HashSet<NNB>(Arrays.asList(new NNB()));
HashSet<NNC> y = new HashSet<NNC>(Arrays.asList(new NNC()));
for (NNB nnb : x) {
inst.printOneDict(nnb);
}
for (NNC nnb : y) {
inst.printOneDict(nnb);
}
System.exit(0);
}
}