Filtrovanie a transformácia zbierok na Guave
1. Prehľad
V tomto výučbe si ukážeme, ako na to filtrujte a transformujte zbierky pomocou Guavy.
Filtrujeme pomocou Predikátov, transformujeme pomocou Funkcií, ktoré poskytuje knižnica a nakoniec uvidíme, ako kombinovať filtrovanie aj transformáciu.
2. Filtrujte zbierku
Začnime jednoduchým príkladom filtrovanie zbierky. Budeme používať predikát poskytnutý knižnicou a zostavený prostredníctvom Predikáty úžitková trieda:
@Test public void whenFilterWithIterables_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Iterable result = Iterables.filter (names, Predicates.containsPattern ("a")); assertThat (result, containsInAnyOrder ("Jane", "Adam")); }
Ako vidíte, filtrujeme Zoznam mien dostávať iba mená, ktoré obsahujú znak „a“ - a my ich používame Iterables.filter () urobiť to.
Prípadne môžeme dobre využiť Collections2.filter () API tiež:
@Test public void whenFilterWithCollections2_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = Collections2.filter (names, Predicates.containsPattern ("a")); assertEquals (2, result.size ()); assertThat (result, containsInAnyOrder ("Jane", "Adam")); result.add ("anna"); assertEquals (5, names.size ()); }
Tu je treba poznamenať niekoľko vecí - najskôr výstup z Collections.filter () je živý pohľad na pôvodnú zbierku - zmeny v jednej sa prejavia v druhej.
Je tiež dôležité pochopiť, že teraz, výsledok je obmedzený predikátom - ak pridáme prvok, ktorý to nevyhovuje Predikát, an IllegalArgumentException bude vyhodené:
@Test (očakáva sa = IllegalArgumentException.class) public void givenFilteredCollection_whenAddingInvalidElement_thenException () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = Collections2.filter (names, Predicates.containsPattern ("a")); result.add ("elvis"); }
3. Napíšte vlastný filter Predikát
Ďalej - napíšme si svoje Predikát namiesto použitia knižnice. V nasledujúcom príklade - definujeme predikát, ktorý dostane iba mená, ktoré začínajú na „A“ alebo „J“:
@Test public void whenFilterCollectionWithCustomPredicate_thenFiltered () {Predicate predicate = new Predicate () {@Override public boolean apply (String input) return input.startsWith ("A")}; Názvy zoznamu = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = Collections2.filter (mená, predikát); assertEquals (3, result.size ()); assertThat (result, containsInAnyOrder ("John", "Jane", "Adam")); }
4. Spojte viac predikátov
Môžeme kombinovať viac predikátov pomocou Predicates.or () a Predicates.and ().
V nasledujúcom príklade - filtrujeme a Zoznam mien, aby ste dostali mená, ktoré začínajú na „J“ alebo neobsahujú „a“:
@Test public void whenFilterUsingMultiplePredicates_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = Collections2.filter (names, Predicates.or (Predicates.containsPattern ("J"), Predicates.not (Predicates.containsPattern ("a")))); assertEquals (3, result.size ()); assertThat (result, containsInAnyOrder ("John", "Jane", "Tom")); }
5. Počas filtrovania kolekcie odstráňte nulové hodnoty
Môžeme vyčistiť nulový hodnoty zo zbierky filtrovaním pomocou Predicates.notNull () ako v nasledujúcom príklade:
@Test public void whenRemoveNullFromCollection_thenRemoved () {List names = Lists.newArrayList ("John", null, "Jane", null, "Adam", "Tom"); Výsledok zbierky = Collections2.filter (names, Predicates.notNull ()); assertEquals (4, result.size ()); assertThat (result, containsInAnyOrder ("John", "Jane", "Adam", "Tom")); }
6. Skontrolujte, či sa všetky prvky v kolekcii zhodujú s podmienkou
Ďalej skontrolujeme, či všetky prvky v kolekcii zodpovedajú určitej podmienke. Použijeme Iterables.all () aby sme skontrolovali, či všetky mená obsahujú „n“ alebo „m“, potom skontrolujeme, či všetky prvky obsahujú „a“:
@Test public void whenCheckingIfAllElementsMatchACondition_thenCorrect () m ")); assertTrue (result); result = Iterables.all (names, Predicates.containsPattern (" a ")); assertFalse (result);
7. Transformujte zbierku
Teraz - pozrime sa, ako na to transformovať kolekciu pomocou Guavy Funkcia. V nasledujúcom príklade - transformujeme a Zoznam mien do a Zoznam z Celé čísla (dĺžka mena) s Iterables.transform ():
@Test public void whenTransformWithIterables_thenTransformed () {Function function = new Function () {@Override public Integer apply (String input) {return input.length (); }}; Názvy zoznamu = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Iterable result = Iterables.transform (názvy, funkcia); assertThat (výsledok, obsahuje (4, 4, 4, 3)); }
Môžeme tiež použiť Collections2.transform () API ako v nasledujúcom príklade:
@ Test public void whenTransformWithCollections2_thenTransformed () {Function func = new Function () {@Override public Integer apply (String input) {return input.length (); }}; Názvy zoznamu = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = Collections2.transform (names, func); assertEquals (4, result.size ()); assertThat (výsledok, obsahuje (4, 4, 4, 3)); výsledok.odstrániť (3); assertEquals (3, names.size ()); }
Všimnite si, že výstup Collections.transform () je živý pohľad na originál Zbierka- zmeny v jednej ovplyvňujú druhú.
A - rovnako ako predtým - ak sa pokúsime pridať do výstupu prvok Zbierka, an UnsupportedOperationException bude vyhodený.
8. Vytvorte Funkcia od Predikát
Môžeme aj tvoriť Funkcia od a Predikát použitím Functions.fromPredicate (). Toto bude samozrejme funkcia, ktorá transformuje vstupy na Boolovský, podľa stavu predikátu.
V nasledujúcom príklade transformujeme a Zoznam mien do zoznamu boolov, kde každý prvok predstavuje, ak názov obsahuje „m“:
@Test public void whenCreatingAFunctionFromAPredicate_thenCorrect () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = Collections2.transform (names, Functions.forPredicate (Predicates.containsPattern ("m"))); assertEquals (4, result.size ()); assertThat (result, contains (false, false, true, true)); }
9. Zloženie dvoch funkcií
Ďalej - poďme sa pozrieť na to, ako transformovať zbierku pomocou zloženého Funkcia.
Functions.compose () vráti zloženie dvoch funkcií, keď použije druhú Funkcia na výstupe prvého Funkcia.
V nasledujúcom príklade - prvom Funkcia názov transformujte na jeho dĺžku, potom druhú Funkcia transformuje dĺžku na a boolovský hodnota, ktorá predstavuje, ak je dĺžka názvu párna:
@Test public void whenTransformingUsingComposedFunction_thenTransformed () {Function f1 = new Function () {@Override public Integer apply (String input) {return input.length (); }}; Funkcia f2 = new Function () {@Override public Boolean apply (Integer input) {return input% 2 == 0; }}; Názvy zoznamu = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = Collections2.transform (names, Functions.compose (f2, f1)); assertEquals (4, result.size ()); assertThat (result, contains (true, true, true, false)); }
10. Kombinujte filtrovanie a transformáciu
A teraz - pozrime sa na ďalšie vynikajúce API, ktoré má Guava - také, ktoré nám skutočne umožní reťaziť filtrovanie a transformáciu dohromady - Plynulé.
V nasledujúcom príklade - filtrujeme Zoznam mien potom transformujte pomocou Plynulé:
@Test public void whenFilteringAndTransformingCollection_thenCorrect () {Predicate predicate = new Predicate () {@Override public boolean apply (String input)}; Funkcia func = new Function () {@Override public Integer apply (String input) {return input.length (); }}; Názvy zoznamu = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Výsledok zbierky = FluentIterable.from (names) .filter (predicate) .transform (func) .toList (); assertEquals (2, result.size ()); assertThat (result, containsInAnyOrder (4, 3)); }
Za zmienku stojí, že v niektorých prípadoch je imperatívna verzia čitateľnejšia a mala by sa uprednostniť pred funkčným prístupom.
11. Záver
Nakoniec sme sa naučili, ako filtrovať a transformovať zbierky pomocou Guavy. Použili sme Collections2.filter () a Iterables.filter () API na filtrovanie, ako aj Collections2.transform () a Iterables.transform () transformovať zbierky.
Nakoniec sme sa rýchlo pozreli na veľmi zaujímavé Plynulé plynulé API, ktoré kombinuje filtrovanie aj transformáciu.
Implementácia všetkých týchto príkladov a útržkov kódu nájdete v projekte GitHub - toto je projekt založený na Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.