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中发现以下错误。放
The method put(capture#5-of ?, capture#6-of ?) in the type Map is not applicable for the arguments (Object, capture#8-of ?)
我不知道如何实例化泛型Map
(我用1Map.class.newInstance()进行了尝试)
有什么想法吗
编辑:在阅读了许多答案之后,问题似乎是如何使filteredAttrs
成为与args
相同类型的实例(Map) args.getClass().newInstance()
似乎起到了作用
# 1 楼答案
这条线
应该抛出实例化异常,因为
Map
是一个接口,除非您实现了自己的名为Map
的类# 2 楼答案
无法实例化映射,因为它是一个接口。不要使用
?
,因为它一开始会造成混乱你有一行什么都不做,所以我删除了它:-
# 3 楼答案
这段代码的问题是,类型系统阻止您将对象放入
Map
中,该对象的键类型为?
。这是因为,如果密钥类型是?
,编译器不知道映射中实际存储的是什么——它可能是Object
,或者Integer
,或者List<Object>
——因此它无法确认您试图添加到映射中的内容实际上是正确的类型,并且不会在Map
中不合适。例如,如果您有此方法:然后编写如下代码:
然后,如果要编译
breakMyMap
中的代码,它会将一对Object
作为键和值放入Map<String, String>
中,打破所有元素都是String
的不变量要解决这个问题,与其让这个函数在
Map<?, ?>
上工作,不如更改该函数,以便获得有关键和值的更多类型信息。例如,您可以尝试以下方法:既然编译器知道密钥类型是
K
,它就可以验证put
不会混淆映射中的密钥类型我应该指出的另一件事是,即使编译了,你的代码也永远不会工作。原因是
将在运行时导致异常,因为
Map
是一个接口,而不是一个类,因此尝试使用newInstance
创建它的实例将无法正常工作。要解决这个问题,您可以显式地指定映射的类型(正如我在上面的代码中所做的),或者获取参数的类:当然,这也不能保证有效,尽管集合的一般约定是所有集合都应该有一个无参数构造函数
希望这有帮助