加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java:通用过滤器映射函数

发布时间:2020-12-15 01:59:56 所属栏目:Java 来源:网络整理
导读:我正在尝试开发一个通用函数来过滤地图. 我到目前为止的代码是: public static Map?,? filterAttrs(Map?,? args,String... unless) { Map?,? filteredAttrs = Map.class.newInstance(); Arrays.sort(unless); for (Object o : args.keySet()) { if (Arrays.
我正在尝试开发一个通用函数来过滤地图.

我到目前为止的代码是:

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中收到以下错误

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()似乎可以解决问题.

解决方法

此代码的问题是类型系统阻止您将对象放入其键类型为?的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();

当然,这也不保证可以工作,尽管集合的一般合同是所有集合都应该有一个无参数的构造函数.

希望这可以帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读