Что именно вы имеете в виду, говоря, что итератор HashMap работает без сбоев, а перечислитель HashTable - нет?

Я искал разницу между двумя классами, и этот момент возник во многих ответах, источником которых был этот блог: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html

Однако я не совсем понимаю. Может ли кто-нибудь уточнить это? Может быть, с примером?

Спасибо, что заглянули!


person GrowinMan    schedule 05.01.2012    source источник


Ответы (3)


Fail-fast означает, что когда вы пытаетесь изменить содержимое, когда вы выполняете итерацию через него, оно завершится ошибкой и выдаст исключение ConcurrentModificationException.

Set keys = hashMap.keySet();
for (Object key : keys) {
    hashMap.put(someObject, someValue); //it will throw the ConcurrentModificationException here
} 

Для перечисления HashTable:

 Enumeration keys = hashTable.keys();
 while (keys.hasMoreElements()) {
          hashTable.put(someKey, someValue);  //this is ok
    }
person evanwong    schedule 05.01.2012
comment
Итераторы Hastable работают безотказно. Его перечислений нет. - person JB Nizet; 06.01.2012

Лучший способ, вероятно, посмотреть исходный код для каждого класса, реализованный реализацией Open JDK для каждого класса; таким образом, вы можете получить ответ прямо из первых уст :-)

Помимо этого, по сути, «быстрый отказ» в этом смысле означает, что итератор над HashMap выдаст исключение, если обнаружит, что другой поток изменил целевой HashMap — если вы посмотрите в источнике для HashMap, вы увидите, что это делается путем простой проверки счетчика количества ожидаемых модификаций. Если количество модификаций отличается от ожидаемого Итератором, это означает, что кто-то еще вошел с момента последней проверки и возился с HashMap, и поэтому Итератор выдает ConcurrentModificationException.

«Неотказоустойчивый» итератор не удосужится проверить и с радостью продолжит свое дело в базовой структуре данных. Таким образом, вы получаете некоторую гибкость (вероятно, сомнительную гибкость в данном случае) в обмен на то, что позже вы, возможно, столкнетесь с ошибками; то есть попытка доступа к значению, которого больше нет.

Как и во всех стратегиях fail-fast, идея заключается в том, что чем раньше будет обнаружена ошибка, тем легче его восстановить или отладить.

person Paul Wostenberg    schedule 05.01.2012
comment
Не просто еще одна ветка. Если вы изменяете карту во время итерации по ней, даже в том же потоке, создается ConcurrentModification (за исключением случаев, когда вы используете сам итератор для изменения карты) - person JB Nizet; 06.01.2012
comment
Очень верно! Иногда сбивающая с толку ошибка, которую я сделал сам :-) - person Paul Wostenberg; 06.01.2012

При вызове iterator.next(), если между моментом создания итератора и моментом вызова next() была сделана какая-либо модификация, немедленно создается исключение ConcurrentModificationException. Вот что значит отказоустойчивость.

Перечисления, возвращаемые Hashtable, не имеют такого поведения. Они предполагают, что вы знаете, что делаете, и их поведение, AFAIK, не определено, если вы изменяете карту во время итерации по ней, используя одно из ее перечислений.

person JB Nizet    schedule 05.01.2012