Я знаю LinkedHashMap
, є передбачуваний порядок ітерації (порядок вставки). Чи підтримує і Set
повернутий LinkedHashMap.keySet()
і Collection
повернутий LinkedHashMap.values()
також цей порядок?
Я знаю LinkedHashMap
, є передбачуваний порядок ітерації (порядок вставки). Чи підтримує і Set
повернутий LinkedHashMap.keySet()
і Collection
повернутий LinkedHashMap.values()
також цей порядок?
Відповіді:
Інтерфейс Map надає три представлення колекції , які дозволяють переглядати вміст карти як набір ключів, збір значень або набір відображень ключових значень. Порядок на карті визначаються як порядок , в якому ітератори на вигляді колекційну карти Повернуться їх елементи. Деякі реалізації карт, як-от
TreeMap
клас, дають конкретні гарантії щодо їх порядку; інші, як іHashMap
клас, не роблять.
- Карта
Цей пов'язаний список визначає порядок ітерації, який зазвичай є порядком введення ключів у карту ( порядок вставки ).
Так що , так, keySet()
, values()
, і entrySet()
(три думки збору згадується) повернені значення в порядку внутрішнього пов'язаного список використання. І так, JavaDoc для цього Map
і LinkedHashMap
гарантує це.
В цьому і полягає сенс цього класу.
Collection
- це лише базовий клас для повернення значень (). Реалізація колекції, яку вона повертає, все ще контролюється LinkedHashMap
. У LinkedHashMap
такому випадку це повернення LinkedValues
екземпляра, приватного класу всередині LinkedHashMap.java.
Map
), яка явно пов'язує порядок карти з ітераторами на видах колекції карти (і чітко пояснює, що це за представлення колекції). Це був для мене недолік.
Дивлячись на джерело, схоже, що це є. keySet()
, values()
і entrySet()
всі використовують один і той же ітератор запису внутрішньо.
Не плутайте LinkedHashMap.keySet()
і не LinkedHashMap.entrySet()
повертайте Комплект, а значить, він не повинен гарантувати замовлення!
Set
інтерфейс з HashSet
, і TreeSet
так далі істоти його реалізації. HashSet
Реалізація Set
інтерфейсу не гарантує порядок. Але TreeSet
робить. Також LinkedHashSet
робить.
Отже, від того, як Set
було реалізовано, залежить, LinkedHashMap
чи гарантуватиме посилання, що повертається, гарантувати замовлення чи ні. Я пройшов вихідний код 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
.
Можна так припустити. Javadoc говорить "передбачуваний порядок ітерації", і єдиними ітераторами, доступними на карті, є ті, які є для keySet (), entrySet () та значень ().
Отже, за відсутності будь-якої подальшої кваліфікації, явно покликане застосуватись до всіх цих ітераторів.
AFAIK це не документально підтверджено, тому ви не можете «формально» припустити цього. Однак навряд чи поточна реалізація зміниться.
Якщо ви хочете забезпечити замовлення, ви, можливо, захочете повторити його на карті і вставити їх у відсортований набір із функцією замовлення на ваш вибір, хоча ви, звичайно, будете платити за ефективність.
Дивлячись на інтерфейс, він повертає звичайну, Set
а не an SortedSet
. Тож гарантій немає.
Перш ніж приймати неявну гарантію, дивлячись на реалізацію (завжди погана ідея), також ознайомтеся з реалізаціями у всіх інших реалізаціях Java :)
Ви можете краще створити, наприклад, TreeSet з keySet в конструкторі.
Я не думаю, що ви можете припускати впорядкування keySet () та значень ().
Я легко можу написати реалізацію LinkedHashMap, яка повертає вам не упорядкований keySet () та значення (), якщо я дотримуюся контракту цих двох методів, визначених у Map, і переосмислених у HashMap.
LinkedHashMap
класу - зберігати впорядкованість елементів під час ітерації карти, і ця поведінка добре визначена. Якщо ви пишете підклас, не дотримуючись специфікації базового класу, ви робите щось дуже неправильно.
values()
, а такожkeySet()
, я розширив питання, щоб включити це. Це означає, що більше запитань може бути закрито як копії цього.