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.