I want to create a map of comparators as following, this map will be used to provide the comparator for each kind of class.
How can I replace the Generic ? in the declaration of my map to be sure that I have always the same Class type in key and value of my map (comparators )?
I want also to reduce the number of warnings
private static final Map<Class<?>, Comparator<?>> comparators = new HashMap<>();
static {
comparators.put(Identifiable.class, new Comparator<Identifiable>() {
@Override
public int compare(Identifiable o1, Identifiable o2) {
return o1.getId().compareTo(o2.getId());
}
});
comparators.put(MyClass.class, new Comparator<MyClass>() {
@Override
public int compare(EIntersection o1, EIntersection o2) {
return o1.getRef().compareTo(o2.getRef());
}
});
...
}
To reduce the amount of warnings you can put a wrapper around your comparator map (like in this answer).
With this solution you have to cast the type only once in your wrapper class (and get only one warning). When calling get on your wrapper class you don't get a warning and don't have to cast the value.
Example:
private static final Map<Class<?>, Comparator<?>> oldComparatorsMap = new HashMap<>();
private static final Map<Class<?>, Comparator<?>> newComparatorsMap = new MyTypeSafeMap();
static {
oldComparatorsMap.put(String.class, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
oldComparatorsMap.put(Integer.class, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
newComparatorsMap.put(String.class, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
newComparatorsMap.put(Integer.class, new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
}
public static void main(String[] args) {
Comparator<String> c1 = (Comparator<String>)oldComparatorsMap.get(String.class); // Warning for every call on get with a cast
Comparator<String> c2 = newComparatorsMap.get(String.class); // No warning here and no cast
}
static class MyTypeSafeMap {
private static final Map<Class<?>, Comparator<?>> innerComparatorsMap = new HashMap<>();
public <T> void put(Class<T> key, Comparator<T> value) {
innerComparatorsMap .put(key, value);
}
public <T> Comparator<T> get(Class<T> key) {
return (Comparator<T>) innerComparatorsMap .get(key); // Only one warning here
// we know it's safe, but the compiler can't prove it
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With