Вопрос-ответ

Is the order of values retrieved from a HashMap the insertion order

Является ли порядок значений, извлекаемых из хэш-карты, порядком вставки

Я пытаюсь определить порядок, в котором извлекаются / могут извлекаться значения в хэш-карте. Вот фрагмент кода для того же.

import java.util.HashMap;

public class HashMapExample {

public static void main(String[] args) {
HashMap<Integer, String> hashmap = new HashMap<Integer, String>();
hashmap.put(1, "apple" );
hashmap.put(2, "lemon" );
hashmap.put(3, "orange" );
hashmap.put(4, "banana" );
hashmap.put(5, "litchi" );
hashmap.put(6, "mango" );
hashmap.put(7, "papaya" );

System.out.println(hashmap.size());

for (String key : hashmap.values()) {
System.out.println(key);
}
}
}

вывод:

7
apple
lemon
orange
banana
litchi
mango
papaya

Значения печатаются в том порядке, в котором они были вставлены. Это верно в целом? Я ожидал, что значения будут напечатаны в произвольном порядке. Для этого используется Java 6.

Переведено автоматически
Ответ 1

Из Javadoc: HashMap "класс не дает никаких гарантий относительно порядка отображения; в частности, он не гарантирует, что порядок будет оставаться постоянным с течением времени".

Если вам нужен согласованный порядок, вы можете использовать LinkedHashMap (для порядка вставки / доступа) или TreeMap (для порядка сравнения). Пожалуйста, обратите внимание, что они поддерживают порядок ключей, а не значений.

Ответ 2

Значения печатаются в том порядке, в котором они были вставлены. Это верно в целом? Я ожидал, что значения будут напечатаны в случайном порядке.


HashMap API не определяет порядок итерации.

Однако, если вы посмотрите на реализацию HashMap, вы можете сделать вывод, что существует сложная временная взаимосвязь между порядком итерации, значениями хэша ключей, порядком, в котором ключи были вставлены, и размером хэш-таблицы. Эта связь скремблируется, если размер хэш-таблицы сам по себе изменяется на1.

В вашем случае вы используете Integer ключи, что означает, что хэш-значения ключей сами являются значениями ключей. Кроме того, вы вставили записи в порядке ключей. Это приводит (случайно!) к порядку итераций, соответствующему порядку вставки. Но если бы вы продолжали вставлять больше ключей, вы бы обнаружили, что порядок итераций "оборачивается". Затем, по мере того как таблица проходит серию изменений размера, порядок будет постепенно все более и более искажаться.

Короче говоря, то, что вы видите, является артефактом реализации хэш-таблицы и конкретного hashCode метода. Это не то, что вы можете (или должны) разумно использовать. Не в последнюю очередь потому, что он может меняться (и изменился) от одного выпуска Java к следующему!


1 - Или в Java 8 или более поздней версии, если перегрузка определенного хэш-блока / хэш-цепочки приводит к переключению их из простого списка в красно-черное дерево. Подробная информация о реализации. Если вам интересно, прочитайте исходный код!

Ответ 3

Вам нужна LinkedHashMap. Из документа следует, что он отличается от HashMap тем, что поддерживает двусвязный список, проходящий через все его записи

Ответ 4

Попробуйте LinkedHashMap, если важен порядок... смотрите в JavaDoc


открытый класс LinkedHashMap расширяет HashMap


Реализация интерфейса Map с хэш-таблицами и связанными списками с предсказуемым порядком итераций. Эта реализация отличается от HashMap тем, что она поддерживает двусвязный список, проходящий через все его записи. Этот связанный список определяет порядок итераций, который обычно соответствует порядку, в котором ключи были вставлены в карту (insertion-order). Обратите внимание, что порядок вставки не изменяется, если ключ повторно вставляется в карту. (Ключ k повторно вставляется в карту m, если вызывается m.put(k, v), когда m.containsKey(k) возвращает true непосредственно перед вызовом.)


java