Я знаю, 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 имеет собственную реализацию Setie 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()я, я расширил вопрос, чтобы включить это. Это означает, что больше вопросов могут быть закрыты как дубликаты этого.