Vodič za Guava Multiset

1. Pregled

U ovom uputstvu istražit ćemo jednu od zbirki Guave - Multiset. Kao java.util.Set, omogućuje učinkovito pohranjivanje i preuzimanje predmeta bez zajamčene narudžbe.

Međutim, za razliku od a Postavi, dopušta više pojavljivanja istog elementa praćenjem broja svakog jedinstvenog elementa koji sadrži.

2. Ovisnost Mavena

Prvo, dodajmo guava ovisnost:

 com.google.guava guava 29,0-jre 

3. Korištenje Multiset

Razmotrimo knjižaru koja ima više primjeraka različitih knjiga. Možda bismo željeli izvesti operacije poput dodavanja kopije, dobivanja broja kopija i uklanjanja jedne kopije kad se proda. Kao Postavi ne dopušta više pojavljivanja istog elementa, ne može se nositi s tim zahtjevom.

Počnimo s dodavanjem kopije naslova knjige. The Multiset treba vratiti da naslov postoji i pružiti nam točno brojanje:

Multiset bookStore = HashMultiset.create (); bookStore.add ("Potter"); bookStore.add ("Potter"); bookStore.add ("Potter"); assertThat (bookStore.contains ("Potter")). isTee (); assertThat (bookStore.count ("Potter")). isEqualTo (3);

Uklonimo sada jednu kopiju. Očekujemo da će se brojanje ažurirati u skladu s tim:

bookStore.remove ("Potter"); assertThat (bookStore.contains ("Potter")). isTee (); assertThat (bookStore.count ("Potter")). isEqualTo (2);

I zapravo, možemo samo postaviti brojanje umjesto izvođenja raznih operacija dodavanja:

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

Multiset potvrđuje računati vrijednost. Ako ga postavimo na negativan, an IlegalArgumentException bačeno je:

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

4. Usporedba s Karta

Bez pristupa Multiset, sve gore navedene operacije mogli bismo postići primjenom vlastite logike koristeći se java.util.Map:

Karta bookStore = novi HashMap (); // dodavanje 3 primjerka bookStore.put ("Potter", 3); assertThat (bookStore.containsKey ("Potter")). isTee (); assertThat (bookStore.get ("Potter")). isEqualTo (3); // uklanjanje 1 primjerka bookStore.put ("Potter", 2); assertThat (bookStore.get ("Potter")). isEqualTo (2);

Kada želimo dodati ili ukloniti kopiju pomoću a Karta, moramo zapamtiti trenutno brojanje i prilagoditi ga u skladu s tim. Također moramo svaki put implementirati ovu logiku u naš pozivni kod ili u tu svrhu stvoriti vlastitu knjižnicu. Naš bi kod također trebao kontrolirati vrijednost argument. Ako ne budemo oprezni, vrijednost bismo lako mogli postaviti na null ili negativan iako su obje vrijednosti nevaljane:

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

Kao što vidimo, puno je prikladnije za upotrebu Multiset umjesto Karta.

5. Istodobnost

Kad želimo koristiti Multiset u istodobnom okruženju, možemo koristiti ConcurrentHashMultiset, koji je siguran za konce Multiset provedba.

Treba imati na umu da zaštita niti ne jamči dosljednost. Koristiti dodati ili ukloniti metode će dobro funkcionirati u okruženju s više niti, ali što ako nekoliko niti naziva setCount metoda?

Ako koristimo setCount metoda, konačni rezultat ovisio bi o redoslijedu izvršavanja preko niti, što se ne može nužno predvidjeti. The dodati i ukloniti metode su inkrementalne, a ConcurrentHashMultiset je u stanju zaštititi svoje ponašanje. Izravno postavljanje brojača nije inkrementalno i zato može istodobno stvoriti neočekivane rezultate.

Međutim, postoji još jedan okus setCount metoda koja ažurira brojanje samo ako se njegova trenutna vrijednost podudara s proslijeđenim argumentom. Metoda vraća true ako je operacija uspjela, oblik optimističnog zaključavanja:

Multiset bookStore = HashMultiset.create (); // ažurira brojanje na 2 ako je trenutno brojanje 0 assertThat (bookStore.setCount ("Potter", 0, 2)). isTrue (); // ažurira brojanje na 5 ako je trenutna vrijednost 50 assertThat (bookStore.setCount ("Potter", 50, 5)). isFalse ();

Ako želimo koristiti setCount metodu u istodobnom kodu, trebali bismo koristiti gornju verziju kako bismo zajamčili dosljednost. Klijent s više niti mogao bi izvesti ponovni pokušaj ako promjena broja ne uspije.

6. Zaključak

U ovom kratkom vodiču razgovarali smo o tome kada i kako koristiti a Multiset, usporedio ga sa standardom Karta i pogledao kako ga najbolje koristiti u istodobnoj aplikaciji.

Kao i uvijek, izvorni kod za primjere možete pronaći na GitHubu.


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