Гарантирован ли порядок возврата ключей и значений из объекта LinkedHashMap? - PullRequest
137 голосов
/ 27 мая 2010

Я знаю, LinkedHashMap имеет предсказуемый порядок итераций (порядок вставки).Set, возвращенный LinkedHashMap.keySet(), и Collection, возвращенный LinkedHashMap.values(), также поддерживают этот порядок?

Ответы [ 7 ]

200 голосов
/ 27 мая 2010

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

- Карта

Этот связанный список определяет итерацию заказ, который обычно заказ в котором ключи были вставлены в карта ( порядок вставки ).

- LinkedHashMap

Итак, да, keySet(), values() и entrySet() (три упомянутых представления коллекции) возвращают значения в порядке, который использует внутренний связанный список. И да, JavaDoc для Map и LinkedHashMap гарантирует это.

В конце концов, в этом смысл этого класса.

11 голосов
/ 27 мая 2010

Глядя на источник, похоже, что так и есть. keySet(), values() и entrySet() все используют один и тот же итератор записи внутри.

7 голосов
/ 01 октября 2015

Не путайте с LinkedHashMap.keySet() и LinkedHashMap.entrySet(), возвращающими Set, и, следовательно, это не должно гарантировать заказ!

Set - это интерфейс с HashSet, TreeSet и т. Д., Являющимися его реализациями. HashSet реализация интерфейса Set не гарантирует порядок. Но TreeSet делает. Также LinkedHashSet делает.

Следовательно, от того, как Set был реализован в LinkedHashMap, зависит, будет ли возвращаемая ссылка Set гарантировать порядок или нет. Я прошел исходный код LinkedHashMap, это выглядит так:

private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}

Таким образом, LinkedHashMap / HashMap имеет собственную реализацию Set, т.е. KeySet. Таким образом, не путайте это с HashSet.

Кроме того, порядок поддерживается тем, как элементы вставляются в ведро. Посмотрите на метод addEntry(..) для LinkedHashMap и сравните его с методом HashMap, который подчеркивает основное различие между HashMap и LinkedHashMap.

5 голосов
/ 28 мая 2010

Вы можете предположить, что так. В Javadoc написано «предсказуемый порядок итераций», и единственные итераторы, доступные в Map , это те итераторы для keySet (), entrySet () и values ​​().

Таким образом, при отсутствии какой-либо дополнительной квалификации он явно предназначен для применения ко всем этим итераторам.

0 голосов
/ 14 ноября 2014

Не думаю, что вы можете предполагать порядок расположения keySet () и values ​​().

Я могу легко написать реализацию LinkedHashMap, которая возвращает вам неупорядоченные keySet () и values ​​(), если я придерживаюсь контракта этих двух методов, которые определены в Map и переопределены в HashMap.

0 голосов
/ 27 мая 2010

AFAIK это не задокументировано, поэтому вы не можете «формально» это предположить. Однако маловероятно, что текущая реализация изменится.

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

0 голосов
/ 27 мая 2010

Глядя на интерфейс, он возвращает просто Set, а не SortedSet. Так что нет никаких гарантий.

Прежде чем принимать неявную гарантию, взглянув на реализацию (всегда плохая идея), также посмотрите на реализации во всех других реализациях Java:)

Вы могли бы лучше создать, например, TreeSet с набором ключей в конструкторе.

...