Коллекция Java: карта обновляется при использовании отказоустойчивого итератора - PullRequest
0 голосов
/ 06 октября 2018

Я работал над анализом отказоустойчивых итераторов с помощью Maps и проверял, будет ли операция обновляться на клоне или на фактической карте

private static void failSafeIterator() {
    ConcurrentHashMap<String, String> map=new ConcurrentHashMap<>();
    map.put("a", "one");
    map.put("b", "two");
    Iterator<String> keyIterator=map.keySet().iterator();
    while(keyIterator.hasNext()){
        String key=keyIterator.next();
        System.out.println(key+":"+map.get(key));
        map.put("c", "three");
        map.put("q", "four");
        map.put("W", "five");

    }
    System.out.println(map.get("q"));

}

Согласно приведенному фрагменту кода,

добавление c, q и w должно было произойти на клоне, а не на фактической коллекции

Но я вижу, что обновление происходит в коллекции.

Вывод также немного сбивает с толку, поскольку не все пары ключ-значение печатаются, даже если ключ присутствует на карте.

Вывод:

a:one 
b:two
c:three
W:five
four

1 Ответ

0 голосов
/ 06 октября 2018

Проблема здесь в том, что вы не понимаете, что означает слабо непротиворечивый итератор, при использовании keySet().iterator(), а именно эта часть документации:

ониГарантируется, что элементы будут пересекаться, поскольку они существовали при строительстве ровно один раз, и могут (но не гарантированы) отражать любые модификации, следующие за конструкцией.

Представьте себе такой случай: вы повторяете ConcurrentHashMap и печатаете все, что у него есть.Как только вы увидели определенное ведро и показали все его элементы, вы переходите к следующему, а также обновляете (предположим, вы добавили к нему пару key-value) предыдущее.Обновления к предыдущему не будут показаны, хотя они существуют.

После вашего цикла вы можете сделать:

System.out.println(map);

И увидеть, что все теперь присутствует.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...