Java:通用过滤器映射函数

标签 java filter map clone

我正在尝试开发一个通用函数来过滤 map 。

我目前的代码是:

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 中。其 key 类型为 ? .这是因为如果 key 类型是 ? ,编译器不知道映射中实际存储了什么——它可能是 Object , 或 Integer , 或 List<Object> - 因此它无法确认您尝试添加到 map 的内容实际上是正确的类型并且不会在 Map 中不合适。 .例如,如果您有此方法:

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 s 作为键和值放入 Map<String, 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, o.toString()) < 0 ) {
            filteredAttrs.put(o, args.get(o));
        }
    }
    return filteredAttrs;
}

现在编译器知道键类型是K , 它可以验证 put不会混淆映射中键的类型。

我应该指出的另一件事是,即使编译成功,您的代码也永远不会工作。原因是行

Map<?, ?> filteredAttrs = Map.class.newInstance();

会在运行时引发异常,因为Map是一个接口(interface),而不是一个类,因此尝试使用 newInstance创建它的实例将无法正常工作。要解决此问题,您可以明确指定 map 的类型(正如我在上面的代码中所做的那样),或者获取参数的类:

Map<K, V> filteredAttrs = args.getClass().newInstance();

当然,这也不能保证有效,尽管集合的一般约定是所有集合应该有一个无参数构造函数。

希望这对您有所帮助!

关于Java:通用过滤器映射函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5060057/

相关文章:

javascript - 如何在对象数组中找到最长长度的数组?

Java序列化

Django过滤器 boolean 不可迭代

未调用 Spring Boot Rest API 过滤器

c++ - 使用 std::map.insert ("xyz"时使用插入函数或仅使用 map[ind] ="xyz"有什么区别

java - JPA - @OneToMany 作为 map

html - 将 css 应用于区域 map

java - 忽略 "Can not deserialize instance of java.util.LinkedHashMap out of START_ARRAY token"错误

java - 我可以访问函数的具体数据吗?

java - 从网页中获取奇怪的字符