Sprievodca multisetom Guava

1. Prehľad

V tomto tutoriáli preskúmame jednu zo zbierok Guava - Multiset. Ako java.util.Set, umožňuje efektívne ukladanie a vyhľadávanie položiek bez zaručenej objednávky.

Avšak na rozdiel od a Nastaviť, umožňuje to viacnásobné výskyty toho istého prvku sledovaním počtu každého jedinečného prvku, ktorý obsahuje.

2. Závislosť od Maven

Najskôr pridajme guava závislosť:

 com.google.guava guava 29.0-jre 

3. Používanie Multiset

Uvažujme o kníhkupectve, ktoré obsahuje viac kópií rôznych kníh. Možno budeme chcieť vykonať operácie, ako je pridanie kópie, získanie počtu kópií a odstránenie jednej kópie, keď sa predáva. Ako Nastaviť neumožňuje viacnásobné výskyty toho istého prvku, nedokáže zvládnuť túto požiadavku.

Začnime pridaním kópie názvu knihy. The Multiset by malo vrátiť, že titul existuje, a poskytnúť nám správny počet:

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

Teraz poďme odstrániť jednu kópiu. Očakávame, že počet bude zodpovedajúcim spôsobom aktualizovaný:

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

A vlastne, môžeme len nastaviť počet namiesto vykonávania rôznych operácií pridania:

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

Multiset potvrdzuje počítať hodnotu. Keby sme to nastavili na záporné, an IllegalArgumentException je hodená:

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

4. Porovnanie s Mapa

Bez prístupu k Multiset, všetky vyššie uvedené operácie by sme mohli dosiahnuť implementáciou vlastnej logiky pomocou java.util.Map:

Map bookStore = nový HashMap (); // pridanie 3 kópií bookStore.put ("Potter", 3); assertThat (bookStore.containsKey ("Potter")). isTrue (); assertThat (bookStore.get ("Potter")). isEqualTo (3); // odstránenie 1 kópie bookStore.put ("Potter", 2); assertThat (bookStore.get ("Potter")). isEqualTo (2);

Keď chceme pridať alebo odstrániť kópiu pomocou a Mapa, musíme si pamätať aktuálny počet a podľa toho ho upraviť. Tiež musíme zakaždým implementovať túto logiku do nášho volacieho kódu alebo na tento účel vybudovať vlastnú knižnicu. Náš kód by tiež musel ovládať hodnotu argument. Ak nebudeme opatrní, môžeme ľahko nastaviť hodnotu na nulový alebo záporné, aj keď sú obe hodnoty neplatné:

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

Ako vidíme, jeho použitie je oveľa pohodlnejšie Multiset namiesto Mapa.

5. Súbežnosť

Keď chceme použiť Multiset v súbežnom prostredí môžeme použiť ConcurrentHashMultiset, ktorý je bezpečný pre vlákna Multiset implementácia.

Mali by sme poznamenať, že bezpečnosť vlákna nie je zárukou konzistencie. Pomocou pridať alebo odstrániť metódy budú fungovať dobre v prostredí s viacerými vláknami, ale čo keď niekoľko vlákien volalo setCount metóda?

Ak použijeme setCount metóda, konečný výsledok by závisel od poradia vykonania naprieč vláknami, ktorú nemožno nevyhnutne predvídať. The pridať a odstrániť metódy sú prírastkové a ConcurrentHashMultiset je schopný chrániť svoje správanie. Priame nastavenie počtu nie je prírastkové, a preto pri súbežnom použití môže spôsobiť neočakávané výsledky.

Existuje však aj iná príchuť setCount metóda, ktorá aktualizuje počet, iba ak sa jeho aktuálna hodnota zhoduje s zadaným argumentom. Metóda vráti true, ak bola operácia úspešná, čo je forma optimistického uzamknutia:

Multiset bookStore = HashMultiset.create (); // aktualizuje počet na 2, ak je aktuálny počet 0 assertThat (bookStore.setCount ("Potter", 0, 2)). isTrue (); // aktualizuje počet na 5, ak je aktuálna hodnota 50 assertThat (bookStore.setCount ("Potter", 50, 5)). isFalse ();

Ak chceme použiť setCount metóda v súbežnom kóde, mali by sme použiť vyššie uvedenú verziu, aby sme zaručili konzistenciu. Klient s viacerými vláknami by mohol vykonať nový pokus, ak zmena počtu zlyhala.

6. Záver

V tomto krátkom návode sme si povedali, kedy a ako používať a Multiset, porovnali s normou Mapa a pozrel sa na to, ako najlepšie ho použiť v súbežnej aplikácii.

Zdrojový kód príkladov nájdete ako vždy na serveri GitHub.


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