Java: generic filter mapping function

I'm trying to develop a general function to filter maps

My code so far is:

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;
}

I'm at filteredatrs The following error was received in put

I don't know how to instantiate a general map (I try to use 1map. Class. Newinstance() `)

Any ideas?

Editor: after reading many answers, the question seems to be how to make filteredattrs an instance of the same type as args (Map)args. getClass(). Newinstance () seems to solve the problem

Solution

The problem with this code is that the type system prevents you from putting an object into its key type? In the map of This is because if the key type is?, The compiler does not know what is actually stored in the map - it can be object, integer, or list < Object > - so it cannot confirm that the content you are trying to add to the map is actually of the correct type and will not be inappropriate in the map For example, if you have this method:

public static void breakMyMap(Map<?,?> m) {
    m.put(new Object(),new Object()); // Won't compile
}

Then write the following code:

Map<String,String> myMap = new HashMap<String,String>();
breakMyMap(myMap);

Then, if the code in breakmymap is to be compiled, it will put a pair of objects as keys and values into map < string, string >, breaking the invariants that all elements are indeed strings

To solve this problem, do not let this function in map Instead, change the function to get more type information with keys and values For example, you can try this:

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;
}

Now that the compiler knows that the key type is k, it can verify that put does not confuse the key types in the map

Another thing I should point out is that the code you have won't work even if compiled The reason is this line

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

This will cause an exception at runtime because map is an interface, not a class, so trying to create an instance of it using newinstance will not work properly To solve this problem, you can explicitly specify the type of map (as I did in the code above), or get the class of parameters:

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

Of course, this is not guaranteed to work, although the general contract of a collection is that all collections should have a parameterless constructor

I hope this can help!

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>