2

如果我在地图实例上UnsupportedOperationException调用方法时不断收到地图内容,如何清空地图内容 ?clear()

4

2 回答 2

2

你不应该。合作对象的契约及其方法有问题。您期望一个可修改的地图,但得到一个不可修改的视图。您应该重新定义合同和/或相应地采用任何实现。如果您无法控制向您传递该地图的那个人,那么它可能有一个原因将其传递给您一个不可修改的视图。

于 2013-02-08T12:39:03.847 回答
0

如果Map是一个UnmodifiableMap(例如,get from ) ,除了创建一个新的引用并清除它之外,Collections.unmodifiableMap()您几乎不能(并且应该)做任何修改。

Map unmodifiable = Collections.unmodifiableMap(m);
Map newMap = new HashMap(unmodifiable);
newMap.clear();
unmodifiable = newMap;

也就是说,实际上可以修改UnmodifiableMap. 事实证明,这Collections.UnmodifiableMap只不过是一个实现Map接口的类,并包装了实际的Map. 它委托包装Map的只读方法,并UnsupportedOperationException在其更改映射的方法的实现中抛出 s。可以Map通过反射获得包装,并因此对其进行修改。

免责声明:考虑到必须非常小心地使用它。如果不可修改的地图是由图书馆或类似机构提供的,它可能会对其性质做出假设,违反合同可能会导致意外/不受欢迎的结果。此外,这可能依赖于可能会在没有通知的情况下更改或版本之间不同的内部结构。

// Creates a standard map
Map<String, String> myMap = new HashMap<String, String>();
myMap.put("1", "a");
myMap.put("2", "b");
// Creates an unmodifiableMap. Actually a wrapper for myMap.
Map unmodifiableMap = Collections.unmodifiableMap(myMap);
System.out.println("Size of unmodifiable map is: " + unmodifiableMap.size());
try{
    // Get classes declared in java.util.Collections
    Class[] classes = Collections.class.getDeclaredClasses();
    for(Class cl : classes) {
        // Look for the UnmodifiableMap class
        if("java.util.Collections$UnmodifiableMap".equals(cl.getName())) {
            // The wrapped Map is in an attribute called "m"
            Field field = cl.getDeclaredField("m");
            field.setAccessible(true);
            // Get the wrapped map
            Object obj = field.get(unmodifiableMap);
            Map map = (Map) obj;
            // modify it
            map.clear();
        }
    }
}
catch (Exception e){ System.out.println(); }
System.out.println("Size of unmodifiable map is: " + unmodifiableMap.size());

(归功于这篇博文

于 2013-02-08T12:04:59.400 回答