Wiem, że LinkedHashMap
ma przewidywalną kolejność iteracji (kolejność reklamowa). Czy Set
zwracane przez LinkedHashMap.keySet()
i Collection
zwracane przez LinkedHashMap.values()
klienta również utrzymują to zamówienie?
Wiem, że LinkedHashMap
ma przewidywalną kolejność iteracji (kolejność reklamowa). Czy Set
zwracane przez LinkedHashMap.keySet()
i Collection
zwracane przez LinkedHashMap.values()
klienta również utrzymują to zamówienie?
Odpowiedzi:
Interfejs mapy udostępnia trzy widoki kolekcji , które umożliwiają przeglądanie zawartości mapy jako zestawu kluczy, zbioru wartości lub zestawu odwzorowań klucz-wartość. Zamówienie z mapy jest zdefiniowany jako takiej kolejności, w której iteratory widokiem na zbiorach MAP wrócić do swoich elementów. Niektóre implementacje map, takie jak
TreeMap
klasa, dają określone gwarancje co do ich kolejności; inni, jakHashMap
klasa, nie.
- Mapa
Ta połączona lista definiuje kolejność iteracji, która zwykle jest kolejnością, w której klucze zostały wstawione do mapy ( kolejność wstawiania ).
Tak, tak keySet()
, values()
, i entrySet()
(trzy widoki kolekcja wspomniano) wartości zwracane w kolejności wewnętrznych związanych zastosowań listy. I tak, JavaDoc Map
i LinkedHashMap
gwarantuje to.
W końcu o to chodzi w tej klasie.
Collection
jest po prostu klasą bazową zwracanych wartości (). Implementacja kolekcji, którą zwraca, jest nadal kontrolowana przez LinkedHashMap
. W tym LinkedHashMap
przypadku zwraca LinkedValues
instancję, prywatną klasę wewnątrz LinkedHashMap.java.
Map
), która wyraźnie wiąże kolejność mapy z iteratorami w widokach kolekcji mapy (i wyjaśnienie, czym są te widoki kolekcji). To był dla mnie brakujący element.
Patrząc na źródło, wygląda na to, że tak. keySet()
, values()
i entrySet()
wszystkie używają wewnętrznie tego samego iteratora wpisu.
Nie daj się mylić z LinkedHashMap.keySet()
i LinkedHashMap.entrySet()
powracającego ustawiony i dlatego nie powinny gwarantować zamawiania!
Set
Jest to interfejs HashSet
, TreeSet
itp istoty jego implementacje. HashSet
Implementacja Set
interfejsu nie gwarantuje uporządkowanie. Ale TreeSet
tak. Też LinkedHashSet
.
W związku z tym zależy to od tego, w jaki sposób Set
zostało zaimplementowane, LinkedHashMap
aby wiedzieć, czy zwracane odniesienie do zestawu zagwarantuje zamówienie, czy nie. Przejrzałem kod źródłowy LinkedHashMap
, wygląda to tak:
private final class KeySet extends AbstractSet<K> {...}
public abstract class AbstractSet<E> extends AbstractCollection<E> implements Set<E> {...}
Zatem LinkedHashMap / HashMap ma własną implementację Set
tj KeySet
. Dlatego nie myl tego zHashSet
.
Kolejność jest również utrzymywana przez sposób wkładania elementów do wiadra. Spójrz na addEntry(..)
metodę LinkedHashMap
i porównaj ją z tą, HashMap
która podkreśla główną różnicę między HashMap
i LinkedHashMap
.
Możesz tak założyć. Javadoc mówi „przewidywalna kolejność iteracji”, a jedynymi dostępnymi iteratorami na mapie są te dla keySet (), entrySet () i values ().
Tak więc w przypadku braku dalszych zastrzeżeń, jest to wyraźnie przeznaczone do zastosowania do wszystkich tych iteratorów.
AFAIK nie jest to udokumentowane, więc nie można tego "formalnie" założyć. Jest jednak mało prawdopodobne, aby obecna implementacja uległa zmianie.
Jeśli chcesz zapewnić porządek, możesz iterować po wpisach mapy i wstawić je do posortowanego zestawu z wybraną funkcją kolejności, chociaż oczywiście będziesz płacić za wydajność.
Patrząc na interfejs, zwraca zwykły, Set
a nie plik SortedSet
. Więc nie ma żadnych gwarancji.
Przed założeniem niejawnej gwarancji, patrząc na implementację (zawsze zły pomysł), spójrz także na implementacje we wszystkich innych implementacjach Java :)
Możesz lepiej utworzyć na przykład TreeSet z zestawem kluczy w konstruktorze.
Nie sądzę, aby można było założyć kolejność keySet () i wartości ().
Mogę łatwo napisać implementację LinkedHashMap, która zwraca ci unordered keySet () i values (), o ile trzymam się kontraktu tych dwóch metod, które są zdefiniowane w Map i nadpisane w HashMap.
LinkedHashMap
klasy jest zachowanie kolejności elementów podczas iteracji mapy, a to zachowanie jest dobrze określone. Jeśli piszesz podklasę bez przestrzegania specyfikacji klasy bazowej, robisz coś bardzo złego.
values()
, a takżekeySet()
, mam pytanie rozszerzony obejmuje to. Oznacza to, że więcej pytań można zamknąć jako duplikaty tego.