Wiem, że LinkedHashMapma przewidywalną kolejność iteracji (kolejność reklamowa). Czy Setzwracane przez LinkedHashMap.keySet()i Collectionzwracane przez LinkedHashMap.values()klienta również utrzymują to zamówienie?
Wiem, że LinkedHashMapma przewidywalną kolejność iteracji (kolejność reklamowa). Czy Setzwracane przez LinkedHashMap.keySet()i Collectionzwracane 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
TreeMapklasa, dają określone gwarancje co do ich kolejności; inni, jakHashMapklasa, 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 Mapi LinkedHashMapgwarantuje to.
W końcu o to chodzi w tej klasie.
Collectionjest po prostu klasą bazową zwracanych wartości (). Implementacja kolekcji, którą zwraca, jest nadal kontrolowana przez LinkedHashMap. W tym LinkedHashMapprzypadku zwraca LinkedValuesinstancję, 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!
SetJest to interfejs HashSet, TreeSetitp istoty jego implementacje. HashSetImplementacja Setinterfejsu nie gwarantuje uporządkowanie. Ale TreeSettak. Też LinkedHashSet.
W związku z tym zależy to od tego, w jaki sposób Setzostało zaimplementowane, LinkedHashMapaby 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ę Settj 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ę LinkedHashMapi porównaj ją z tą, HashMapktóra podkreśla główną różnicę między HashMapi 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, Seta 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.
LinkedHashMapklasy 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.