假设我有一个带有以下签名的方法:
<T,U extends Comparable<? super U>> Comparator<T> method(Map<String,Function<? super T,? extends U>> comparatorFunctionMap)
该方法接受函数映射(使用字符串键)并创建比较器< T>.结果(如何重要).映射值是Function< ;?的实例超级T,?扩展U>,以便它们可以直接传递给Comparator.comparing().
如何以类型安全的方式填充此地图?假设我有一个具有属性名称和年龄的人员(以及他们的getters).
当我执行以下操作时:
Map<String,Function<? super Person,? extends Comparable>> map1 = new HashMap<>(); map1.put("name",Person::getName); method(map1);
我在第1行和第3行收到警告.如果我尝试这样做,例如:
Map<String,? extends Comparable<?>>> map2 = new HashMap<>(); map2.put("name",Person::getName); method(map2);
第三行是编译错误.
有没有办法安全地做这种类型?
解决方法
如果你想在地图中添加Person :: getName和Person :: getAge,你将无法使用你提出的方法签名,因为没有U是String,Integer和可比.
基本上,您的地图是Map< String,Function< T,Comparable<?>>因为可比对象在类型方面彼此无关.
我不认为你可以在不使用原始类型的情况下绕过它,这可能如下所示.请注意,您仍然具有类型安全性(您必须将Comparable传递给地图).
static void m() { Map<String,Function<Person,Comparable<?>>> map = new HashMap<>(); map.put("name",Person::getName); map.put("age",Person::getAge); Comparator<Person> c = method(map); } @SuppressWarnings(value = {"unchecked","rawtypes"}) static <T> Comparator<T> method(String name,Map<String,Function<T,Comparable<?>>> comparatorFunctionMap) { Function f = (Function) comparatorFunctionMap.get("age"); Comparator<T> c = Comparator.comparing(f); return c; }
唯一(我认为)这个限制是从技术上讲,可以通过一个奇怪的类说Weird实现Comparable< String>这可能会导致运行时错误.