有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java是不可修改的,映射会快速失败

是从集合返回的映射。不可修改的映射失败很快

换句话说,如果其他人使用地图的“可修改视图”修改地图,它是否会抛出concurrentModificationExceptioniterating


共 (3) 个答案

  1. # 1 楼答案

    下面是一个更新的示例,显示抛出了异常(谢谢@jarnbjo):

    final Map<Integer, String> original = new HashMap<Integer, String>();
    final int capacity = 1000 * 100;
    for (int i = 0; i < capacity; i++) {
      original.put(i, UUID.randomUUID().toString());
    }
    final Map<Integer, String> unmodifiable = Collections.unmodifiableMap(original);
    
    ExecutorService executor = Executors.newFixedThreadPool(2);
    for (int k = 0; k < 5; k++) {
      executor.execute(new Runnable() {
    
      @Override
      public void run() {
    
        Random r = new Random();
        int c = original.size();
        for (int i = c; i < c + 1000; i++) {
        original.put(i, UUID.randomUUID().toString());
    
        }
      }
      });
    
      executor.execute(new Runnable() {
    
      @Override
      public void run() {
    
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<Integer, String> entry : unmodifiable.entrySet()) {
        sb.append(entry.getValue()).append(' ');
        }
        System.out.println("sb.toString().length() = " + sb.toString().length());
      }
      });
    }
    
  2. # 2 楼答案

    不,它们不会很快失败

    虽然没有特别提到,但API文档说明“返回映射上的查询操作”读取“指定映射”,并尝试修改返回的映射…,会导致“UnsupportedOperationException”。由于不可修改的映射仅委托给原始映射,因此有关使用原始映射的所有限制也与不可修改包装器相关

  3. # 3 楼答案

    由于API没有定义行为,因此它依赖于实现,也就是说,它可能会根据您使用的Java运行时而有所不同

    对于Sun Java 6运行时,其行为似乎将从正在包装的映射中继承。不过,正如我所说,这是明智的行为,并不能保证跨实现

    编辑-Sun Java 6的测试用例:

    import java.util.Collections;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    
    
    public class TestUnmod {
        public static void main(String[] args) {
            Map<String,String> map = new HashMap();
            map.put("a", "a");
            map.put("b", "b");
            map.put("c", "c");
    
            Map<String,String> unmod = Collections.unmodifiableMap(map);
            Iterator<String> it = unmod.values().iterator();
            System.out.println(it.next());
            map.put("d", "d");
            System.out.println(it.next());
        }
    }
    

    输出:

    b
    Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
        at java.util.HashMap$ValueIterator.next(HashMap.java:822)
        at java.util.Collections$UnmodifiableCollection$1.next(Collections.java:1010)
        at TestUnmod.main(TestUnmod.java:18)