Vodič za TreeMap u Javi

1. Pregled

U ovom ćemo članku istražiti TreeMap provedba Karta sučelje iz Java Collections Framework (JCF).

TreeMap je implementacija mape koja zadržava svoje unose sortirane prema prirodnom redoslijedu ključeva ili još bolje koristeći usporedbu ako je korisnik osigurao u vrijeme izrade.

Prije smo pokrivali HashMap i LinkedHashMap implementacije i shvatit ćemo da postoji podosta podataka o tome kako rade ove klase koji su slični.

Spomenute je članke toplo preporučiti za čitanje prije nego što nastavite s ovim.

2. Zadano sortiranje TreeMap

Prema zadanim postavkama, TreeMap sortira sve svoje unose prema njihovom prirodnom redoslijedu. Za cijeli broj to bi značilo uzlazni poredak, a za nizove abecedni red.

Pogledajmo prirodni poredak u testu:

@Test javna praznina givenTreeMap_whenOrdersEntriesNaturally_thenCorrect () {Map TreeMap = nova TreeMap (); map.put (3, "val"); map.put (2, "val"); map.put (1, "val"); map.put (5, "val"); map.put (4, "val"); assertEquals ("[1, 2, 3, 4, 5]", map.keySet (). toString ()); }

Primijetimo da smo cjelobrojne ključeve postavili na neuredan način, ali prilikom dohvaćanja skupa ključeva potvrđujemo da se oni doista održavaju u rastućem redoslijedu. To je prirodni poredak cijelih brojeva.

Isto tako, kada koristimo nizove, oni će biti poredani u svom prirodnom redoslijedu, tj. Abecedno:

@Test javna praznina givenTreeMap_whenOrdersEntriesNaturally_thenCorrect2 () {Map TreeMap = nova TreeMap (); map.put ("c", "val"); map.put ("b", "val"); map.put ("a", "val"); map.put ("e", "val"); map.put ("d", "val"); assertEquals ("[a, b, c, d, e]", map.keySet (). toString ()); }

TreeMapza razliku od hash mape i povezane hash mape, nigdje ne koristi princip raspršivanja jer ne koristi polje za spremanje svojih unosa.

3. Prilagođeno sortiranje TreeMap

Ako nismo zadovoljni prirodnim uređenjem TreeMap, također možemo definirati vlastito pravilo za naručivanje pomoću usporedbe tijekom izrade karte stabla.

U donjem primjeru želimo da se cjelobrojni ključevi poredaju silaznim redoslijedom:

@Test javna praznina givenTreeMap_whenOrdersEntriesByComparator_thenCorrect () {Map TreeMap = nova TreeMap (Comparator.reverseOrder ()); map.put (3, "val"); map.put (2, "val"); map.put (1, "val"); map.put (5, "val"); map.put (4, "val"); assertEquals ("[5, 4, 3, 2, 1]", map.keySet (). toString ()); }

Mapa raspršivanja ne jamči redoslijed pohranjenih ključeva i posebno ne jamči da će ovaj redoslijed ostati isti tijekom vremena, ali karta stabla jamči da će ključevi uvijek biti sortirani prema navedenom redoslijedu.

4. Važnost TreeMap Sortiranje

Sad to znamo TreeMap pohranjuje sve svoje unose u sortiranom redoslijedu. Zbog ovog atributa mapa stabala možemo izvoditi upite poput; pronađi „najveći“, pronađi „najmanji“, pronađi sve ključeve manje ili veće od određene vrijednosti itd.

Kôd u nastavku pokriva samo mali postotak ovih slučajeva:

@Test javna praznina givenTreeMap_whenPerformsQueries_thenCorrect () {Map TreeMap = nova TreeMap (); map.put (3, "val"); map.put (2, "val"); map.put (1, "val"); map.put (5, "val"); map.put (4, "val"); Cjeloviti najvišiKey = map.lastKey (); Cjeloviti najniži ključ = map.firstKey (); Postavite keysLessThan3 = map.headMap (3) .keySet (); Postavite keysGreaterThanEqTo3 = map.tailMap (3) .keySet (); assertEquals (novi cijeli broj (5), najvišiKljuč); assertEquals (novi cijeli broj (1), najniži ključ); assertEquals ("[1, 2]", keysLessThan3.toString ()); assertEquals ("[3, 4, 5]", keysGreaterThanEqTo3.toString ()); }

5. Interna provedba TreeMap

TreeMap provodi NavigableMap sučelje i temelji svoj interni rad na načelima crveno-crnih stabala:

javna klasa TreeMap proširuje AbstractMap implementira NavigableMap, Cloneable, java.io.Serializable

Načelo crveno-crnih stabala izvan je dosega ovog članka, međutim, postoje ključne stvari koje trebate upamtiti kako biste razumjeli kako se uklapaju u TreeMap.

Kao prvo, crveno-crno stablo je struktura podataka koja se sastoji od čvorova; zamislite obrnuto stablo manga s korijenom na nebu i granama koje rastu prema dolje. Korijen će sadržavati prvi element dodan stablu.

Pravilo je da je počevši od korijena, bilo koji element u lijevoj grani bilo kojeg čvora uvijek manji od elementa u samom čvoru. Oni s desne strane su uvijek veći. Što definira veće ili manje od određenog je prirodnim uređenjem elemenata ili definiranom usporedbom pri gradnji, kao što smo vidjeli ranije.

Ovo pravilo jamči da će unosi mape stabla uvijek biti poredani i predvidljivi redoslijedom.

Drugo, crveno-crno stablo je samobalansirajuće binarno stablo pretraživanja. Ovaj atribut i gore navedeno jamče da osnovne operacije poput pretraživanja, dobivanja, stavljanja i uklanjanja oduzimaju logaritamsko vrijeme O (zapisnik n).

Ovdje je ključno samobalansiranje. Dok nastavljamo s umetanjem i brisanjem unosa, slikajte kako drvo raste dulje na jednom rubu ili kraće na drugom.

To bi značilo da bi operacija trebala kraće vrijeme na kraćoj grani i dulje vrijeme na grani koja je najudaljenija od korijena, nešto što ne bismo željeli da se dogodi.

Stoga se o tome vodi računa pri dizajniranju crveno-crnih stabala. Za svako umetanje i brisanje održava se maksimalna visina stabla na bilo kojem rubu O (zapisnik n) tj. stablo se kontinuirano uravnotežuje.

Baš kao i hash karta i povezana hash karta, karta stabla nije sinkronizirana i stoga su pravila za njezinu upotrebu u višenitnom okruženju slična onima u druge dvije implementacije karte.

6. Odabir prave karte

Pogledavši HashMap i LinkedHashMap implementacije ranije i sada TreeMap, važno je napraviti kratku usporedbu između njih tri koja će nas voditi o tome koja od njih gdje odgovara.

Heš karta dobra je kao implementacija mape opće namjene koja omogućuje brzo spremanje i pronalaženje podataka. Međutim, to nedostaje zbog svog kaotičnog i neurednog rasporeda unosa.

To uzrokuje lošu izvedbu u scenarijima gdje postoji puno iteracija, jer cjelokupni kapacitet temeljnog niza utječe na zaokret koji nije samo broj unosa.

Povezana hash karta posjeduje dobre atribute hash karata i dodaje redoslijed unosima. Bolje se izvodi tamo gdje ima puno ponavljanja, jer se uzima u obzir samo broj unosa bez obzira na kapacitet.

Karta stabla uzima narudžbu na sljedeću razinu pružajući potpunu kontrolu nad načinom sortiranja tipki. S druge strane, nudi lošije opće performanse od druge dvije alternative.

Mogli bismo reći a povezana hash karta smanjuje kaos u redoslijedu hash mape bez nanošenja kazne za izvedbu mape stabla.

7. Zaključak

U ovom smo članku istražili Javu TreeMap razred i njegova interna provedba. Budući da je posljednja u nizu uobičajenih implementacija sučelja Map, nastavili smo i ukratko raspraviti gdje najbolje odgovara u odnosu na druge dvije.

Potpuni izvorni kod za sve primjere korištene u ovom članku možete pronaći u projektu GitHub.