Является ли карта / порядок сбора стабильным между вызовами? - PullRequest
4 голосов
/ 02 июня 2010

Если у меня есть хэш-карта и я многократно повторяю объекты, верно ли, что мне не гарантирован один и тот же порядок для каждого вызова? Например, может ли следующая строка вывести две строки, которые отличаются друг от друга:

Map<String,Integer> map = new HashMap<String,Integer>()
  {{ put("a", 1); put("b", 2); put("c", 3); }};
System.out.println(map);
System.out.println(map);

И так ли это для наборов и коллекций в целом? Если да, то как лучше всего в случае, если вам придется дважды повторять одну и ту же коллекцию в одном и том же порядке (независимо от того, какой это порядок)? Я думаю, преобразование в список.

Ответы [ 5 ]

7 голосов
/ 02 июня 2010

Контракты Map и Set не дают никаких гарантий относительно порядка итерации, но контракты SortedSet и SortedMap (реализованные TreeMap и TreeSet) делают.

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

3 голосов
/ 02 июня 2010

При использовании HashMap нет никакой гарантии, что порядок итераций будет одинаковым на каждой итерации.

Вместо этого рассмотрим LinkedHashMap, , который является хеш-таблицей с предсказуемым порядком итерации.

3 голосов
/ 02 июня 2010

вы правы, порядок карты не гарантируется. Возможно, вы захотите посмотреть на что-то вроде TreeMap , если вам нужно, чтобы порядок оставался неизменным между вызовами.

сказав, что, скорее всего, код напечатает одну и ту же вещь дважды, это просто не гарантируется.

2 голосов
/ 02 июня 2010

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

Это хороший пример спецификации de facto . Это правда, что в письме спецификации не указано, что это будет так. Тем не менее, каждая отдельная коллекция JDK ведет себя таким образом (при условии, что в случае упорядоченного доступа LinkedHashMap, вы выполняете все итерации каждый раз). И трудно представить реализацию коллекции, которая бы не имела этого свойства. Я реализовал и просмотрел множество коллекций, и только однажды я рассмотрел коллекцию, которая каждый раз будет повторяться по-разному; это был чрезвычайно странный случай, и я закончил тем, что выкинул всю идею, потому что повторение по-разному каждый раз было слишком чертовски странным (то есть нарушало эту де-факто спецификацию, которую я упомянул).

Так что я говорю, продолжайте и зависите от этого. Это не общая рекомендация зависеть от любого старого неопределенного поведения, которое вы хотите. Но в этом случае тебе просто не повредит.

1 голос
/ 02 июня 2010

Хотя спецификация библиотеки не гарантирует, что порядок останется неизменным со временем, он, вероятно, будет идентичен, пока базовая структура данных (то есть массивы, которые реализуют хэш-таблицу) не будут изменены. Поэтому, если вы не вставляете и не удаляете элементы из хеш-таблицы, не исключено, что порядок ввода не изменится.

Рассмотрение типичной реализации HashMap показывает, что это так, например: http://www.docjar.com/html/api/java/util/HashMap.java.html

Как говорится, это не то, что ваш код должен полагаться.

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