Is there a way to create a class which implements Comparator and allows only a singleton instance to be created, or failing that only one instance per parameterized type?
I have tried a couple of mechanisms (both using a private constructor and then a getInstance method) but neither was valid syntax. So I'm wondering if type erasure means that it's impossible to rely on a single instance of a generic Comparator class.
The aim is to avoid having dozens of instances of the class, because all will behave identically and so a sole instance seems desirable. Is it possible? If not, what is the suggested way to avoid wild duplication of Comparator instances?
EDIT: This question seems to have caused confusion about what I'm trying to achieve, so I'll paste one of my broken attempts here. The code below is an attempt to create a Map which holds only a single instance of the Comparator for each type T. This is valid syntax, but I'm unable to call the getInstance
method because I have no way to get a Class<T>
instance in the client code.
final class IntervalComparator<T extends Comparable<T>> implements
Comparator<Interval<T>> {
// Private constructor. Use the getInstance method instead.
private IntervalComparator() {
}
// Map to hold one instance for each type.
private static Map<Class, IntervalComparator> cacheMap = new HashMap<>();
// The only method which returns an instance of this Comparator.
public static <K extends Comparable<K>> IntervalComparator<K>
getInstance(Class<K> type) {
IntervalComparator<K> soleInstance = cacheMap.get(type);
if(soleInstance == null) {
soleInstance = new IntervalComparator<>();
cacheMap.put(type, soleInstance);
}
return soleInstance;
}
@Override
public int compare(Interval<T> o1, Interval<T> o2) {
// ... Comparison code goes here ...
}
}
The client code looks like this:
private Set<Interval<T>> intervalSet;
private IntervalUnion(IntervalUnion.Builder<T> builder) {
this.intervalSet = new TreeSet<>(new IntervalComparator<T>());
// ... add Interval<T> objects into intervalSet ...
}
At the moment it is creating a new IntervalComparator<T>
object each time it is called, and I don't think there's any way to pass Class<T>
to the getInstance
method.