HashSet og TreeSet-sammenligning

1. Introduksjon

I denne artikkelen skal vi sammenligne to av de mest populære Java-implementeringene av java.util.Sett grensesnitt - HashSet og TreeSet.

2. Forskjeller

HashSet og TreeSet er blader av samme gren, men de skiller seg ut i få viktige saker.

2.1. Bestilling

HashSet lagrer gjenstandene i tilfeldig rekkefølge, mens TreeSet bruker den naturlige ordenen til elementene. La oss se følgende eksempel:

@Test offentlig ugyldighet givenTreeSet_whenRetrievesObjects_thenNaturalOrder () {Set set = new TreeSet (); set.add ("Baeldung"); set.add ("er"); set.add ("Awesome"); assertEquals (3, set.size ()); assertTrue (set.iterator (). neste (). er lik ("Awesome")); }

Etter å ha lagt til String gjenstander inn i TreeSet, ser vi at den første er “Awesome”, selv om den ble lagt til helt på slutten. En lignende operasjon gjort med HashSet garanterer ikke at rekkefølgen på elementene vil forbli konstant over tid.

2.2. Null Objekter

En annen forskjell er at HashSet kan lagre null gjenstander, mens TreeSet tillater ikke dem:

@Test (forventet = NullPointerException.class) offentlig tomrom givenTreeSet_whenAddNullObject_thenNullPointer () {Set set = new TreeSet (); set.add ("Baeldung"); set.add ("er"); set.add (null); } @Test offentlig ugyldighet givenHashSet_whenAddNullObject_thenOK () {Set set = new HashSet (); set.add ("Baeldung"); set.add ("er"); set.add (null); assertEquals (3, set.size ()); }

Hvis vi prøver å lagre null objekt i en TreeSetvil operasjonen resultere i et kast NullPointerException. Det eneste unntaket var i Java 7 da det var tillatt å ha nøyaktig ett null element i TreeSet.

2.3. Opptreden

For å si det enkelt, HashSet er raskere enn TreeSet.

HashSet gir konstant ytelse for de fleste operasjoner som legge til(), fjerne() og inneholder (), kontra Logg(n) tid som tilbys av TreeSet.

Vanligvis kan vi se det utførelsestiden for å legge til elementer i TreeSet er mye bedre enn for HashSet.

Husk at JVM kanskje ikke blir varmet opp, så utførelsestidene kan variere. En god diskusjon om hvordan du designer og utfører mikrotester ved hjelp av forskjellige Sett implementeringer er tilgjengelig her.

2.4. Implementerte metoder

TreeSet er rik på funksjoner, implementere flere metoder som:

  • pollFirst () - for å returnere det første elementet, eller null hvis Sett er tom
  • pollLast () - for å hente ut og fjerne det siste elementet, eller returnere null hvis Sett er tom
  • først() - for å returnere den første varen
  • siste()for å returnere den siste varen
  • tak() - å returnere det minste elementet som er større enn eller lik det gitte elementet, eller null hvis det ikke er noe slikt element
  • Nedre() - å returnere det største elementet strengt mindre enn det gitte elementet, eller null hvis det ikke er noe slikt element

Metodene nevnt ovenfor gjør TreeSet mye lettere å bruke og kraftigere enn HashSet.

3. Likheter

3.1. Unike elementer

Både TreeSet og HashSet garanterer a duplikatfri samling av elementer, som det er en del av det generiske Sett grensesnitt:

@Test offentlig ugyldighet givenHashSetAndTreeSet_whenAddDuplicates_thenOnlyUnique () {Set set = new HashSet (); set.add ("Baeldung"); set.add ("Baeldung"); assertTrue (set.size () == 1); Sett set2 = nytt TreeSet (); set2.add ("Baeldung"); set2.add ("Baeldung"); assertTrue (set2.size () == 1); }

3.2. Ikke synkronisert

Ingen av de beskrevne Sett implementeringer er synkronisert. Dette betyr at hvis flere tråder får tilgang til a Sett samtidig, og minst en av trådene endrer den, så må den synkroniseres eksternt.

3.3. Fail-fast Iterators

De Iterators returnert av TreeSet og HashSet er feilrask.

Det betyr at enhver endring av Sett når som helst etter Iterator er opprettet vil kaste a ConcurrentModificationException:

@Test (forventet = ConcurrentModificationException.class) offentlig ugyldig givenHashSet_whenModifyWhenIterator_thenFailFast () {Set set = new HashSet (); set.add ("Baeldung"); Iterator it = set.iterator (); while (it.hasNext ()) {set.add ("Awesome"); it.next (); }}

4. Hvilken implementering skal du bruke?

Begge implementeringene oppfyller kontrakten med ideen om et sett, så det er opp til konteksten hvilken implementering vi kan bruke.

Her er noen få poeng å huske:

  • Hvis vi vil holde oppføringene sortert, må vi gå for TreeSet
  • Hvis vi verdsetter ytelse mer enn minneforbruk, bør vi gå for HashSet
  • Hvis vi har lite minne, bør vi gå for TreeSet
  • Hvis vi ønsker å få tilgang til elementer som er relativt nær hverandre i henhold til deres naturlige rekkefølge, vil vi kanskje vurdere TreeSet fordi den har større lokalitet
  • HashSetYtelsen kan stilles inn ved hjelp av initialCapacity og loadFactor, som ikke er mulig for TreeSet
  • Hvis vi vil bevare innsettingsordren og dra nytte av konstant tidstilgang, kan vi bruke LinkedHashSet

5. Konklusjon

I denne artikkelen dekket vi forskjellene og likhetene mellom TreeSet og HashSet.

Som alltid er kodeeksemplene for denne artikkelen tilgjengelig på GitHub.


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