Java:通用过滤器映射函数
我正在尝试开发一个通用函数来过滤地图.
我到目前为止的代码是: public static Map<?,?> filterAttrs(Map<?,?> args,String... unless) { Map<?,?> filteredAttrs = Map.class.newInstance(); Arrays.sort(unless); for (Object o : args.keySet()) { if (Arrays.binarySearch(unless,o.toString()) < 0 ) { filteredAttrs.put(o,args.get(o)); } } return filteredAttrs; } 我在filteredAttrs.put中收到以下错误
我不知道如何实例化一个通用Map(我尝试使用1Map.class.newInstance()`). 有任何想法吗? 编辑:在阅读了许多答案后,问题似乎是如何使filteredAttrs成为与args相同类型的实例. (Map)args.getClass().newInstance()似乎可以解决问题. 解决方法
此代码的问题是类型系统阻止您将对象放入其键类型为?的Map中.这是因为如果键类型是?,则编译器不知道实际存储在映射中的是什么 – 它可以是Object,Integer,或List< Object> – 因此它无法确认您尝试添加到地图中的内容实际上是否为正确类型,并且不会在地图中不合适.例如,如果您有此方法:
public static void breakMyMap(Map<?,?> m) { m.put(new Object(),new Object()); // Won't compile } 然后编写如下代码: Map<String,String> myMap = new HashMap<String,String>(); breakMyMap(myMap); 然后,如果breakMyMap中的代码要编译,它会将一对Object作为键和值放入Map< String,String>中,打破所有元素确实是字符串的不变量. 要解决这个问题,不要让这个函数在Map<?,?>上运行,而是更改函数,以便获得有关键和值的更多类型信息.例如,你可以试试这个: public static <K,V> Map<K,V> filterAttrs(Map<K,V> args,String... unless) { Map<K,V> filteredAttrs = new HashMap<K,V>(); Arrays.sort(unless); for (K o : args.keySet()) { String attr = o.toString(); if (Arrays.binarySearch(unless,args.get(o)); } } return filteredAttrs; } 现在编译器知道密钥类型是K,它可以验证put不会混淆map中键的类型. 我应该指出的另一件事是你所拥有的代码即使编译也不会有效.原因是这条线 Map<?,?> filteredAttrs = Map.class.newInstance(); 将在运行时导致异常,因为Map是一个接口,而不是一个类,因此尝试使用newInstance创建它的实例将无法正常工作.要解决这个问题,您可以显式指定地图的类型(正如我在上面的代码中所做的那样),或者获取参数的类: Map<K,V> filteredAttrs = args.getClass().newInstance(); 当然,这也不保证可以工作,尽管集合的一般合同是所有集合都应该有一个无参数的构造函数. 希望这可以帮助! (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |