Порядок значений, извлекаемых из HashMap, порядок вставки - PullRequest
51 голосов
/ 27 января 2010

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

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.

Ответы [ 5 ]

81 голосов
/ 27 января 2010

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

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

61 голосов
/ 27 января 2010

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

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

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

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

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

10 голосов
/ 27 января 2010

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

5 голосов
/ 27 января 2010

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

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

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

1 голос
/ 27 января 2010

Связанной коллекцией является java.util.concurrent's ConcurrentSkipListMap . skiplist позволяет просматривать записи в ключевом порядке, а также просматривать их в случайном порядке (но не так быстро, как в HashMap).

Есть хороший скиплист Демонстрационный апплет .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...