Skorzystałem LinkedHashMap
bo ważna jest kolejność w jakiej wpisywano klucze na mapie.
Ale teraz chcę uzyskać wartość klucza na pierwszym miejscu (pierwszy wpisany wpis) lub na końcu.
Czy powinna istnieć taka metoda first()
i last()
czy coś takiego?
Czy muszę mieć iterator, aby uzyskać tylko pierwszy wpis klucza? Dlatego użyłem LinkedHashMap
!
Dzięki!
java
dictionary
linkedhashmap
maiky
źródło
źródło
Odpowiedzi:
Semantyka
LinkedHashMap
jest nadal semantyka Map, a nie aLinkedList
. Zachowuje kolejność reklam, tak, ale jest to szczegół implementacji, a nie aspekt interfejsu.Najszybszym sposobem uzyskania „pierwszego” wpisu jest nadal
entrySet().iterator().next()
. Uzyskanie „ostatniego” wpisu jest możliwe, ale pociągnie za sobą iterację po całym zestawie przez wywołanie,.next()
aż dotrzesz do ostatniego.while (iterator.hasNext()) { lastElement = iterator.next() }
edycja : Jeśli jednak chcesz wyjść poza API JavaSE, Apache Commons Collections ma własną
LinkedMap
implementację, która ma metody takie jakfirstKey
ilastKey
, które robią to, czego szukasz. Interfejs jest znacznie bogatszy.źródło
mylinkedmap.entrySet().iterator().next()
złożoność czasowa? Czy to O (1)?Czy możesz spróbować zrobić coś takiego (aby uzyskać ostatni wpis):
źródło
T last = null ; for( T item : linkedHashMap.values() ) last = item;
Czy jakoś tak. To jest O (N) w czasie, ale O (1) w pamięci.Wiem, że przyszedłem za późno, ale chciałbym zaproponować kilka alternatyw, nie coś niezwykłego, ale kilka przypadków, o których nikt tutaj nie wspomniał. W przypadku, gdy komuś nie zależy tak bardzo na wydajności, ale chce czegoś bardziej prostego (być może znaleźć ostatnią wartość wpisu z jedną linią kodu), wszystko to zostanie dość uproszczone wraz z pojawieniem się Java 8 . Podaję kilka przydatnych scenariuszy.
Ze względu na kompletność zestawiam te alternatywy z rozwiązaniami tablic, o których wspominali już w tym poście inni użytkownicy. Podsumowuję wszystkie przypadki i myślę, że byłyby przydatne (gdy wydajność ma znaczenie lub nie), szczególnie dla nowych programistów, zawsze zależy od istoty każdego problemu
Możliwe alternatywy
Wykorzystanie metody tablicowej
Wziąłem to z poprzedniej odpowiedzi do, aby dokonać następujących porównań. To rozwiązanie należy do @feresr.
Wykorzystanie metody ArrayList
Podobne do pierwszego rozwiązania z nieco inną wydajnością
Zmniejsz metodę
Ta metoda zredukuje zestaw elementów do momentu pobrania ostatniego elementu strumienia. Ponadto zwróci tylko wyniki deterministyczne
Metoda SkipFunction
Ta metoda pozwoli uzyskać ostatni element strumienia, po prostu pomijając wszystkie elementy przed nim
Iterowalna alternatywa
Oto pełny kod źródłowy
Oto wynik z wydajnością każdej metody
źródło
LinkedHashMap
obecna implementacja (Java 8) śledzi swój koniec. Jeśli problemem jest wydajność i / lub mapa ma duży rozmiar, możesz uzyskać dostęp do tego pola poprzez odbicie.Ponieważ implementacja może się zmienić, prawdopodobnie dobrym pomysłem jest również posiadanie strategii awaryjnej. Możesz chcieć zarejestrować coś, jeśli zostanie zgłoszony wyjątek, aby wiedzieć, że implementacja uległa zmianie.
Może to wyglądać następująco:
źródło
ClassCastException
że nacatch
wszelki wypadektail
nie jestEntry
w podklasie (lub przyszłej implementacji).Jeszcze jednym sposobem uzyskania pierwszego i ostatniego wpisu w LinkedHashMap jest użycie metody „toArray” interfejsu Set.
Ale myślę, że iterowanie wpisów w zestawie wpisów i uzyskanie pierwszego i ostatniego wpisu jest lepszym podejściem.
Użycie metod tablicowych prowadzi do ostrzeżenia o postaci „... wymaga niesprawdzonej konwersji, aby była zgodna z ...”, której nie można naprawić [ale można ją wyłączyć tylko za pomocą adnotacji @SuppressWarnings („unchecked”)].
Oto mały przykład pokazujący użycie metody „toArray”:
źródło
To trochę brudne, ale możesz zastąpić
removeEldestEntry
metodę LinkedHashMap, którą możesz zrobić jako prywatny anonimowy członek:Dzięki temu zawsze będziesz mógł uzyskać pierwszy wpis u swojego
eldest
członka. Będzie aktualizowany za każdym razem, gdy wykonaszput
.Powinien być również łatwy do zastąpienia
put
i ustawieniayoungest
...Jednak wszystko się psuje, gdy zaczniesz usuwać wpisy; nie wymyśliłem sposobu, żeby to rozgryźć.
To bardzo irytujące, że w inny sposób nie można uzyskać rozsądnego dostępu do głowy lub ogona ...
źródło
Może coś takiego:
źródło
Sugestia:
źródło
Polecam użycie ConcurrentSkipListMap, która ma
firstKey()
ilastKey()
metodyźródło
Do użycia pierwszego elementu
entrySet().iterator().next()
i zatrzymaj iterację po 1 iteracji. Ostatnim najłatwiejszym sposobem jest zachowanie klucza w zmiennej za każdym razem, gdy robisz map.put.źródło
Chociaż linkedHashMap nie zapewnia żadnej metody uzyskania pierwszego, ostatniego ani żadnego konkretnego obiektu.
Ale to dość trywialne, aby uzyskać:
Ustaw al = orderMap.keySet ();
teraz używam iteratora na obiekcie al; możesz dostać dowolny przedmiot.
źródło
Tak, natrafiłem na ten sam problem, ale na szczęście potrzebuję tylko pierwszego elementu ... - Tak właśnie zrobiłem.
Jeśli potrzebujesz również ostatniego elementu - przyjrzałbym się, jak odwrócić kolejność twojej mapy - zapisz go w zmiennej tymczasowej, uzyskaj dostęp do pierwszego elementu w odwróconej mapie (dlatego byłby to twój ostatni element), zabij zmienna temp.
Oto kilka dobrych odpowiedzi, jak odwrócić kolejność haszowania:
Jak iterować hashmap w odwrotnej kolejności w Javie
Jeśli korzystasz z pomocy z powyższego linku, przekaż im pozytywne głosy :) Mam nadzieję, że to może komuś pomóc.
źródło
tak, musisz ręcznie wyliczyć zestaw kluczy do końca listy połączonej, a następnie pobrać wpis według klucza i zwrócić ten wpis.
źródło
źródło