Что именно вы подразумеваете под итератором HashMap - он работает быстро, а перечислитель HashTable - нет?
Я искал разницу между этими двумя классами, и этот вопрос возник во многих ответах, поскольку этот блог является источником: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
Однако я не совсем понимаю. Может кто-нибудь уточнить это? Возможно с примером?
Спасибо за просмотр!
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
}
Лучше всего, вероятно, посмотреть на исходный код для каждого класса, реализованный реализацией Open JDK для каждого класса; таким образом, вы можете получить ответ прямо изо рта лошади, как бы это было:-)
Помимо этого, по сути, "fast-fast" в этом смысле означает, что Iterator поверх HashMap сгенерирует исключение, если обнаружит, что другой поток изменил целевой HashMap - если вы посмотрите в источнике для HashMap, вы увидите, что это делается просто путем проверки счетчика на количество ожидаемых модификаций. Если количество модификаций отличается от ожидаемого Итератора, это означает, что кто-то еще вошел после последней проверки и запутался с HashMap, и поэтому Итератор выдает исключение ConcurrentModificationException.
Итератор, не подверженный сбоям, не потрудится проверить и с удовольствием проведет свой бизнес в базовой структуре данных. Таким образом, вы получаете некоторую гибкость (возможно, сомнительную гибкость в этом случае) в обмен на возможную ошибку позже; т.е. пытается получить доступ к значению, которого больше нет.
Как и во всех отказоустойчивых стратегиях, идея заключается в том, что чем раньше будет обнаружена ошибка, тем легче будет ее устранить или отладить.
При звонке iterator.next()
, если была произведена какая-либо модификация между моментом создания итератора и моментом next()
вызывается, немедленно генерируется исключение ConcurrentModificationException. Вот что означает отказоустойчивость.
Перечисления, возвращаемые Hashtable, не имеют такого поведения. Они предполагают, что вы знаете, что делаете, и их поведение, AFAIK, не определено, если вы изменяете карту, перебирая ее, используя одно из перечислений.