Ответ 1
Прежде всего, это полностью зависит от того, какой тип Карты вы используете. Но поскольку поток JavaRanch говорит о HashMap, я буду считать, что это реализация, о которой вы говорите. И давайте предположим, что вы говорите о стандартной реализации API от Sun/Oracle.
Во-вторых, если вы беспокоитесь о производительности при повторении своей хэш-карты, я предлагаю вам взглянуть на LinkedHashMap
. Из документов:
Итерация по представлениям коллекции LinkedHashMap требует времени, пропорционального размеру карты, независимо от ее емкости. Итерация над HashMap, вероятно, будет более дорогой, требуя времени, пропорционального ее пропускной способности.
HashMap.entrySet()
Исходный код для этой реализации доступен. Реализация в основном просто возвращает новый HashMap.EntrySet
. Класс, который выглядит следующим образом:
private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
public Iterator<Map.Entry<K,V>> iterator() {
return newEntryIterator(); // returns a HashIterator...
}
// ...
}
и a HashIterator
выглядит как
private abstract class HashIterator<E> implements Iterator<E> {
Entry<K,V> next; // next entry to return
int expectedModCount; // For fast-fail
int index; // current slot
Entry<K,V> current; // current entry
HashIterator() {
expectedModCount = modCount;
if (size > 0) { // advance to first entry
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
}
final Entry<K,V> nextEntry() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
Entry<K,V> e = next;
if (e == null)
throw new NoSuchElementException();
if ((next = e.next) == null) {
Entry[] t = table;
while (index < t.length && (next = t[index++]) == null)
;
}
current = e;
return e;
}
// ...
}
Итак, у вас есть это... Это код, который диктует, что произойдет, когда вы перейдете через entrySet. Он проходит через весь массив, который до тех пор, пока емкость карт.
HashMap.keySet() и .get()
Здесь вам сначала нужно получить набор ключей. Это занимает время, пропорциональное емкости карты (в отличие от размера для LinkedHashMap). После этого вы вызываете get()
один раз для каждой клавиши. Конечно, в среднем случае с хорошей реализацией hashCode это занимает постоянное время. Тем не менее, это неизбежно потребует много вызовов .hashCode
и .equals
, что, очевидно, займет больше времени, чем просто вызов entry.value()
.