如何在Comparator地图中使用泛型来避免警告

时间:2017-10-25 08:11:45

标签: java generics

我想创建一个比较器的映射如下,这个映射将用于为每种类提供比较器。

如何更换Generic?在我的地图的声明中,以确保我的地图(比较器)的键和值始终具有相同的类类型?

我还希望减少警告数量

 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());
        }
    });
    ...
}

1 个答案:

答案 0 :(得分:4)

要减少警告的数量,您可以在比较器地图(like in this answer)周围放置一个包装器。

使用此解决方案,您必须在包装器类中仅转换一次类型(并且只获得一个警告)。当你在你的包装类上调用get时,你不会收到警告,也不必抛出值。

示例:

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
  }
}