W Javie, czy istnieje obiekt, który działa jak mapa do przechowywania i uzyskiwania dostępu do par klucz / wartość, ale może zwrócić uporządkowaną listę kluczy i uporządkowaną listę wartości, tak że listy kluczy i wartości są w tej samej kolejności?
Więc jako wyjaśnienie po kodzie szukam czegoś, co zachowuje się jak moja fikcyjna mapa zamówień:
OrderedMap<Integer, String> om = new OrderedMap<>();
om.put(0, "Zero");
om.put(7, "Seven");
String o = om.get(7); // o is "Seven"
List<Integer> keys = om.getKeys();
List<String> values = om.getValues();
for(int i = 0; i < keys.size(); i++)
{
Integer key = keys.get(i);
String value = values.get(i);
Assert(om.get(key) == value);
}
java
collections
Co to
źródło
źródło
LinkedHashMap
.Odpowiedzi:
SortedMap interfejs (z realizacją TreeMap ) powinien być twoim przyjacielem.
Interfejs ma następujące metody:
keySet()
który zwraca zestaw kluczy w kolejności rosnącejvalues()
który zwraca kolekcję wszystkich wartości w porządku rosnącym odpowiednich kluczyInterfejs ten spełnia dokładnie Twoje wymagania. Klucze muszą jednak mieć znaczącą kolejność. W przeciwnym razie możesz użyć LinkedHashMap, gdzie kolejność jest ustalana na podstawie kolejności wstawiania.
źródło
LinkedHashMap
w której kolejności iteracji jest kolejność, w której jej wpisy były ostatnio otwieraneLinkedHashMap
kolejność iteracji to kolejność wstawiania, ale zamiast tego można użyć innego konstruktora, aby określić kolejność dostępu. docs.oracle.com/javase/8/docs/api/java/util/…Szukasz java.util.LinkedHashMap . Otrzymasz listę par Map.Entry <K, V> , które zawsze są iterowane w tej samej kolejności. Ta kolejność jest taka sama, jak kolejność umieszczania elementów. Alternatywnie, użyj java.util.SortedMap , gdzie klucze muszą mieć naturalną kolejność lub mieć ją określoną przez
Comparator
.źródło
keySet()
metoda skutecznie zwraca LinkedHashSet, który odzwierciedla kolejność twoichput()
wywołań. Pamiętaj, że wielokrotne połączenia zput()
tym samym kluczem nie zmienią kolejności, chyba żeremove()
wcześniej klucz.LinkedHashMap
w której kolejności iteracji jest kolejność, w której ostatnio uzyskano dostęp do jej wpisówLinkedHashMap zachowuje porządek kluczy.
Wygląda na to, że java.util.LinkedHashMap działa tak samo jak normalna HashMap.
źródło
Myślę, że najbliższą kolekcją, którą otrzymasz z frameworka, jest SortedMap
źródło
Możesz wykorzystać interfejs NavigableMap , do którego można uzyskać dostęp i przejść w kolejności rosnącej lub malejącej. Ten interfejs ma zastąpić interfejs SortedMap. Nawigowalna mapa jest zwykle sortowana zgodnie z naturalną kolejnością jej klawiszy lub według Komparatora dostępnego w czasie tworzenia mapy.
Istnieją trzy najbardziej użyteczne implementacje go: TreeMap , ImmutableSortedMap i ConcurrentSkipListMap .
Przykład TreeMap:
Wynik:
źródło
Myślę, że interfejs SortedMap wymusza to, o co prosisz, a TreeMap to implementuje.
http://java.sun.com/j2se/1.5.0/docs/api/java/util/SortedMap.html http://java.sun.com/j2se/1.5.0/docs/api/java/util /TreeMap.html
źródło
Od wersji Java 6 istnieje również nieblokująca bezpieczna dla wątków alternatywa dla TreeMap . Zobacz ConcurrentSkipListMap .
źródło
tl; dr
Aby utrzymać
Map< Integer , String >
porządek posortowany według klucza, użyj jednej z dwóch klas implementujących interfejsySortedMap
/NavigableMap
:TreeMap
ConcurrentSkipListMap
Jeśli manipulujesz mapą w jednym wątku, użyj pierwszego
TreeMap
,. Jeśli manipulowania drugiej nici, użyj drugiego,ConcurrentSkipListMap
.Aby uzyskać szczegółowe informacje, zobacz poniższą tabelę i następującą dyskusję.
Detale
Oto tabela graficzna, którą stworzyłem, pokazującą funkcje dziesięciu
Map
implementacji dołączonych do Java 11.NavigableMap
Interfejs jest to, coSortedMap
powinno być na pierwszym miejscu.SortedMap
Logicznie powinien być usunięty, ale nie może być tak niektóre implementacje map 3rd-Party można za pomocą interfejsu.Jak widać w tej tabeli, tylko dwie klasy implementują interfejsy
SortedMap
/NavigableMap
:TreeMap
ConcurrentSkipListMap
Oba te klucze trzymają w uporządkowanej kolejności, według ich naturalnej kolejności (przy użyciu
compareTo
metodyComparable
( https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ Comparable.html ) interfejs) lub przezComparator
przekazaną implementację. Różnica między tymi dwiema klasami polega na tym, że drugaConcurrentSkipListMap
, jest bezpieczna dla wątków , wysoce współbieżna .Zobacz także kolumnę Kolejność iteracji w poniższej tabeli.
LinkedHashMap
Klasa zwraca swoje wpisy w kolejności, w jakiej zostały one pierwotnie wstawionego .EnumMap
zwraca wpisy w kolejności, w której zdefiniowana jest klasa enum klucza . Na przykład mapa, której pracownik pokrywa, który dzień tygodnia (Map< DayOfWeek , Person >
) korzysta zDayOfWeek
klasy enum wbudowanej w Javę. To wyliczenie jest zdefiniowane w poniedziałek pierwszy i niedziela ostatni. Wpisy w iteratorze pojawią się w tej kolejności.Pozostałe sześć implementacji nie obiecuje kolejności zgłoszeń.
źródło
Użyłem mapy Simple Hash, połączonej listy i kolekcji, aby posortować mapę według wartości.
Dane wyjściowe to:
źródło