Guide til Guava Multiset

1. Oversigt

I denne vejledning udforsker vi en af ​​Guava-samlingerne - Multisæt. Som en java.util.Set, det giver mulighed for effektiv opbevaring og hentning af varer uden en garanteret ordre.

Men i modsætning til en Sæt, det giver mulighed for flere forekomster af det samme element ved at spore antallet af hvert unikt element, det indeholder.

2. Maven-afhængighed

Lad os først tilføje guava afhængighed:

 com.google.guava guava 29.0-jre 

3. Brug Multisæt

Lad os overveje en boghandel, der har flere kopier af forskellige bøger. Vi vil muligvis udføre handlinger som at tilføje en kopi, få antallet af kopier og fjerne en kopi, når den er solgt. Som en Sæt tillader ikke flere forekomster af det samme element, det kan ikke håndtere dette krav.

Lad os komme i gang ved at tilføje kopier af en bogtitel. Det Multisæt skal vende tilbage, at titlen eksisterer og give os det korrekte antal:

Multiset bookStore = HashMultiset.create (); bookStore.add ("Potter"); bookStore.add ("Potter"); bookStore.add ("Potter"); assertThat (bookStore.contains ("Potter")). isTrue (); assertThat (bookStore.count ("Potter")). er EqualTo (3);

Lad os nu fjerne en kopi. Vi forventer, at optællingen opdateres i overensstemmelse hermed:

bookStore.remove ("Potter"); assertThat (bookStore.contains ("Potter")). isTrue (); assertThat (bookStore.count ("Potter")). er EqualTo (2);

Og faktisk, vi kan bare indstille optællingen i stedet for at udføre forskellige tilføjelsesoperationer:

bookStore.setCount ("Potter", 50); assertThat (bookStore.count ("Potter")). er EqualTo (50);

Multisæt validerer tælle værdi. Hvis vi sætter det til negativt, an IllegalArgumentException kastes:

assertThatThrownBy (() -> bookStore.setCount ("Potter", -1)) .isInstanceOf (IllegalArgumentException.class);

4. Sammenligning med Kort

Uden adgang til Multisæt, kunne vi opnå alle ovenstående operationer ved at implementere vores egen logik ved hjælp af java.util.Map:

Map bookStore = ny HashMap (); // tilføjelse af 3 eksemplarer bookStore.put ("Potter", 3); assertThat (bookStore.containsKey ("Potter")). isTrue (); assertThat (bookStore.get ("Potter")). er EqualTo (3); // fjernelse af 1 kopi bookStore.put ("Potter", 2); assertThat (bookStore.get ("Potter")). er EqualTo (2);

Når vi vil tilføje eller fjerne en kopi ved hjælp af en Kort, skal vi huske det aktuelle antal og justere det i overensstemmelse hermed. Vi har også brug for at implementere denne logik i vores kaldekode hver gang eller konstruere vores eget bibliotek til dette formål. Vores kode skal også kontrollere værdi argument. Hvis vi ikke er forsigtige, kunne vi nemt indstille værdien til nul eller negativ, selvom begge værdier er ugyldige:

bookStore.put ("Potter", null); assertThat (bookStore.containsKey ("Potter")). isTrue (); bookStore.put ("Potter", -1); assertThat (bookStore.containsKey ("Potter")). erTrue (); 

Som vi kan se, er det meget mere praktisk at bruge Multisæt i stedet for Kort.

5. Samtidighed

Når vi vil bruge Multisæt i et samtidig miljø kan vi bruge ConcurrentHashMultiset, som er trådsikker Multisæt implementering.

Vi skal bemærke, at det at være trådsikkert ikke garanterer dog konsistens. Bruger tilføje eller fjerne metoder fungerer godt i et miljø med flere tråde, men hvad nu hvis flere tråde kaldte setCount metode?

Hvis vi bruger setCount metode, det endelige resultat ville afhænge af rækkefølgen af ​​udførelse på tværs af tråde, som ikke nødvendigvis kan forudsiges. Det tilføje og fjerne metoderne er trinvise, og ConcurrentHashMultiset er i stand til at beskytte deres adfærd. At indstille optællingen direkte er ikke trinvis, og det kan derfor medføre uventede resultater, når de bruges samtidigt.

Der er dog en anden smag af setCount metode, der kun opdaterer optællingen, hvis dens aktuelle værdi svarer til det godkendte argument. Metoden vender tilbage, hvis operationen lykkedes, en form for optimistisk låsning:

Multiset bookStore = HashMultiset.create (); // opdaterer antallet til 2, hvis det aktuelle antal er 0 assertThat (bookStore.setCount ("Potter", 0, 2)). isTrue (); // opdaterer antallet til 5, hvis den aktuelle værdi er 50 assertThat (bookStore.setCount ("Potter", 50, 5)). isFalse ();

Hvis vi vil bruge setCount metode i samtidig kode, skal vi bruge ovenstående version for at garantere konsistens. En klient med flere tråde kunne udføre et forsøg igen, hvis ændring af antallet ikke lykkedes.

6. Konklusion

I denne korte vejledning diskuterede vi, hvornår og hvordan man bruger en Multisæt, sammenlignede det med en standard Kort og kiggede på, hvordan det bedst kan bruges i en samtidig applikation.

Som altid kan kildekoden til eksemplerne findes på GitHub.


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