Прежде всего, позвольте мне упомянуть, что разница в производительности, о которой мы говорим, вряд ли стоит учитывать. Фраза «Таким образом, очень важно не устанавливать слишком высокую начальную емкость (или слишком низкий коэффициент загрузки), если важна производительность итерации», вводит в заблуждение. Это не очень важно. Я бы лучше сформулировал это так: «Таким образом, вы можете не захотеть устанавливать начальную емкость ...»
Теперь, когда мы получили это, давайте перейдем к фактическому ответу.
Это связано с тем, как организована внутренняя структура данных хеш-карты по сравнению с простой организацией списка.
Стандартная реализация хеш-карты использует список «сегментов», где каждый блок представляет собой связанный список узлов. Ключи и значения хранятся в этих узлах. Список сегментов не является плотно заполненным, что означает, что многие записи null
.
Поэтому, чтобы пройти все ключи карты, вы должны пройти список сегментов, и для каждого сегмента пройти узлы в сегменте.
Поскольку узлов столько же, сколько и ключей, обход узлов имеет такую же сложность по времени, как и обход всего 1014 *, но тогда в случае хэш-карты мы также должны посчитать накладные расходы по ходу списка ведер. И чем больше «начальный размер» хэш-карты или чем меньше коэффициент заполнения, тем больше будет null
сегментов, что означает, что в списке сегментов, которые вы будете посещать, будет больше записей, только чтобы узнать, что они null
и перейти к следующей записи.
Итак, обход HashMap
немного дороже, чем обход ArrayList
.
Но, поверьте мне, разница настолько мала, что на самом деле ее не стоит рассматривать. Никто никогда не заметит. Гораздо лучше использовать правильную структуру данных для ваших целей и не беспокоиться о незначительном выигрыше в производительности. Правильная структура данных - это всегда структура данных, которая дает наиболее элегантное решение. Самое элегантное решение - это то, которое легче всего прочитать и понять, что оно делает и как оно делает.