Я знаю, LinkedHashMap
имеет предсказуемый порядок итераций (порядок вставки). Поддерживает ли Set
возвращенный LinkedHashMap.keySet()
и Collection
возвращаемый LinkedHashMap.values()
также этот порядок?
Я знаю, LinkedHashMap
имеет предсказуемый порядок итераций (порядок вставки). Поддерживает ли Set
возвращенный LinkedHashMap.keySet()
и Collection
возвращаемый LinkedHashMap.values()
также этот порядок?
Ответы:
Интерфейс Map предоставляет три вида коллекций , которые позволяют просматривать содержимое карты в виде набора ключей, набора значений или набора отображений ключ-значение. Порядок на карте определяются как порядок , в котором итераторы на виде коллекционную карты Возвратятся их элементы. Некоторые реализации карт, такие как
TreeMap
класс, дают определенные гарантии относительно их порядка; другие, какHashMap
класс, не делают.
- Карта
Этот связанный список определяет порядок итераций, который обычно является порядком, в котором ключи были вставлены в карту ( порядок вставки ).
Так что , да, keySet()
, values()
, и entrySet()
(три мнения сбора упоминается) возвращаемые значения в порядке внутреннего связанного список использование. И да, JavaDoc для Map
и LinkedHashMap
гарантировать его.
В этом смысл этого класса, в конце концов.
Collection
- это просто базовый класс, для которого возвращается values (). Реализация коллекции, которую он возвращает, все еще контролируется LinkedHashMap
. В этом LinkedHashMap
случае он возвращает LinkedValues
экземпляр, закрытый класс внутри LinkedHashMap.java.
Map
), которая явно связывает порядок карты с итераторами в представлениях коллекции карты (и проясняете, каковы эти представления коллекции). Это был недостающий кусок для меня.
Глядя на источник, похоже, что так и есть. keySet()
, values()
и entrySet()
все используют один и тот же итератор записи внутри.
Не путайте 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
ie KeySet
. Таким образом, не путайте это с HashSet
.
Кроме того, порядок поддерживается тем, как элементы вставляются в ведро. Посмотрите на addEntry(..)
метод LinkedHashMap
и сравните его с тем, HashMap
который подчеркивает основное различие между HashMap
и LinkedHashMap
.
Вы можете предположить, что так. В Javadoc написано «предсказуемый порядок итераций», и единственные итераторы, доступные на карте, - это те, которые предназначены для keySet (), entrySet () и values ().
Таким образом, при отсутствии какой-либо дополнительной квалификации он явно предназначен для применения ко всем этим итераторам.
AFAIK это не задокументировано, поэтому вы не можете «формально» предполагать это Однако маловероятно, что текущая реализация изменится.
Если вы хотите обеспечить порядок, вы можете перебрать все карты и вставить их в отсортированный набор с выбранной вами функцией заказа, хотя, естественно, вы будете платить за производительность.
Глядя на интерфейс, он возвращает простой, Set
а не SortedSet
. Так что нет никаких гарантий.
Прежде чем принять на себя неявную гарантию, взглянув на реализацию (всегда плохая идея), также посмотрите на реализации во всех других реализациях Java :)
Вы могли бы лучше создать, например, TreeSet с keySet в конструкторе.
Я не думаю, что вы можете предполагать порядок keySet () и values ().
Я могу легко написать реализацию LinkedHashMap, которая возвращает вам неупорядоченные keySet () и values (), если я придерживаюсь контракта этих двух методов, которые определены в Map и переопределены в HashMap.
LinkedHashMap
класса является сохранение порядка элементов во время итерации карты, и это поведение хорошо определено. Если вы пишете подкласс без соблюдения спецификации базового класса, то вы делаете что-то очень неправильное.
values()
так иkeySet()
я, я расширил вопрос, чтобы включить это. Это означает, что больше вопросов могут быть закрыты как дубликаты этого.