Usporedba HashSet-a i TreeSet-a

1. Uvod

U ovom ćemo članku usporediti dvije najpopularnije Java implementacije java.util.Set sučelje - HashSet i TreeSet.

2. Razlike

HashSet i TreeSet su listovi iste grane, ali se razlikuju u nekoliko važnih stvari.

2.1. Naručivanje

HashSet pohranjuje predmete slučajnim redoslijedom, dok TreeSet primjenjuje prirodni poredak elemenata. Pogledajmo sljedeći primjer:

@Test javna praznina givenTreeSet_whenRetrievesObjects_thenNaturalOrder () {Set set = new TreeSet (); set.add ("Baeldung"); set.add ("je"); set.add ("Awesome"); assertEquals (3, set.size ()); assertTrue (set.iterator (). next (). jednako ("Awesome")); }

Nakon dodavanja Niz predmeti u TreeSet, vidimo da je prvi „Awesome“, iako je dodan na samom kraju. Slična operacija izvedena sa HashSet ne garantira da će redoslijed elemenata tijekom vremena ostati konstantan.

2.2. Nula Predmeti

Druga razlika je ta HashSet može pohraniti null predmeti, dok TreeSet ne dopušta im:

@Test (očekuje se = NullPointerException.class) javna praznina givenTreeSet_whenAddNullObject_thenNullPointer () {Set set = new TreeSet (); set.add ("Baeldung"); set.add ("je"); set.add (null); } @Test javna praznina givenHashSet_whenAddNullObject_thenOK () {Set set = new HashSet (); set.add ("Baeldung"); set.add ("je"); set.add (null); assertEquals (3, set.size ()); }

Ako pokušamo pohraniti null objekt u a TreeSet, operacija će rezultirati bacanjem NullPointerException. Jedina iznimka bila je u Javi 7 kada je smjela imati točno jednu null element u TreeSet.

2.3. Izvođenje

Jednostavno rečeno, HashSet je brži od TreeSet.

HashSet pruža konstantne performanse za većinu operacija poput dodati(), ukloniti() i sadrži (), naspram zapisnik(n) vrijeme koje nudi TreeSet.

Obično to možemo vidjeti vrijeme izvršenja za dodavanje elemenata u TreeSet je mnogo bolji nego za HashSet.

Imajte na umu da JVM možda nije zagrijan pa se vremena izvršavanja mogu razlikovati. Dobra diskusija o tome kako dizajnirati i izvoditi mikrotestove koristeći razne Postavi implementacije je dostupna ovdje.

2.4. Primijenjene metode

TreeSet bogat je funkcionalnostima, implementirajući dodatne metode poput:

  • anketaPrvo () - za vraćanje prvog elementa, ili null ako Postavi prazno je
  • pollLast () - za dohvaćanje i uklanjanje posljednjeg elementa ili povratak null ako Postavi prazno je
  • prvi() - za povratak prve stavke
  • posljednji()za povratak posljednjeg predmeta
  • strop() - vratiti najmanji element veći ili jednak zadanom elementu, ili null ako takvog elementa nema
  • niži() - vratiti najveći element strogo manje od zadanog elementa, ili null ako takvog elementa nema

Gore spomenute metode čine TreeSet mnogo jednostavniji za upotrebu i moćniji od HashSet.

3. Sličnosti

3.1. Jedinstveni elementi

Oba TreeSet i HashSet jamstvo a kolekcija elemenata bez duplikata, jer je dio generičkog Postavi sučelje:

@Test javna praznina givenHashSetAndTreeSet_whenAddDuplicates_thenOnlyUnique () {Set set = new HashSet (); set.add ("Baeldung"); set.add ("Baeldung"); assertTrue (set.size () == 1); Set set2 = new TreeSet (); set2.add ("Baeldung"); set2.add ("Baeldung"); assertTrue (set2.size () == 1); }

3.2. Ne sinkronizirano

Ništa od opisanog Postavi implementacije su sinkronizirano. To znači da ako više niti pristupa a Postavi istodobno, a barem ga jedna od niti modificira, tada se mora sinkronizirati izvana.

3.3. Iteratori s brzim neuspjehom

The Iteratorvratio do TreeSet i HashSet su neuspješni.

To znači da svaka izmjena Postavi u bilo koje vrijeme nakon Iterator stvoreno će baciti a ConcurrentModificationException:

@Test (očekuje se = ConcurrentModificationException.class) javna praznina givenHashSet_whenModifyWhenIterator_thenFailFast () {Set set = new HashSet (); set.add ("Baeldung"); Iterator it = set.iterator (); while (it.hasNext ()) {set.add ("Awesome"); it.next (); }}

4. Koju implementaciju koristiti?

Obje implementacije ispunjavaju ugovor ideje skupa, tako da ovisi o kontekstu koju bismo implementaciju mogli koristiti.

Evo nekoliko brzih točaka koje treba zapamtiti:

  • Ako svoje unose želimo sortirati, trebamo odabrati TreeSet
  • Ako performanse cijenimo više od potrošnje memorije, trebali bismo se odlučiti za HashSet
  • Ako nam nedostaje pamćenja, trebali bismo ići na TreeSet
  • Ako želimo pristupiti elementima koji su relativno blizu jedan drugome prema njihovom prirodnom rasporedu, možda bismo trebali razmotriti TreeSet jer ima veći lokalitet
  • HashSetIzvedba se može podesiti pomoću početni kapacitet i loadFactor, što nije moguće za TreeSet
  • Ako želimo sačuvati redoslijed umetanja i imati koristi od stalnog vremenskog pristupa, možemo koristiti LinkedHashSet

5. Zaključak

U ovom smo članku pokrili razlike i sličnosti između TreeSet i HashSet.

Kao i uvijek, primjeri koda za ovaj članak dostupni su na GitHubu.


$config[zx-auto] not found$config[zx-overlay] not found