Filtriranje i pretvaranje zbirki u Guavi
1. Pregled
U ovom uputstvu ilustrirat ćemo kako filtrirajte i transformirajte zbirke s Guavom.
Filtrirat ćemo pomoću predikata, transformirati pomoću funkcija koje knjižnica pruža i na kraju ćemo vidjeti kako kombinirati i filtriranje i transformiranje.
2. Filtrirajte zbirku
Počnimo s jednostavnim primjerom filtriranje zbirke. Koristit ćemo izvanredni predikat koji je osigurala knjižnica i konstruirao ga putem Predikati klasa korisnosti:
@Test public void whenFilterWithIterables_thenFiltered () {Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Iterable rezultat = Iterables.filter (imena, predikati.containsPattern ("a")); assertThat (rezultat, sadržiInAnyOrder ("Jane", "Adam")); }
Kao što vidite, filtriramo Popis imena da bismo dobili samo ona imena koja sadrže znak "a" - a mi ih koristimo Iterables.filter () to učiniti.
Alternativno, možemo dobro iskoristiti Collections2.filter () API također:
@Test public void whenFilterWithCollections2_thenFiltered () {Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = Collections2.filter (imena, predikati.contensPattern ("a")); assertEquals (2, result.size ()); assertThat (rezultat, sadržiInAnyOrder ("Jane", "Adam")); result.add ("anna"); assertEquals (5, names.size ()); }
Ovdje treba napomenuti nekoliko stvari - prvo, rezultat Collections.filter () je pogled uživo na izvornu kolekciju - promjene na jednom odrazit će se na druge.
Također je važno shvatiti da sada, rezultat ograničava predikat - ako dodamo element koji to ne zadovoljava Predikat, an IlegalArgumentException bit će bačen:
@Test (očekuje se = IllegalArgumentException.class) javna praznina givenFilteredCollection_whenAddingInvalidElement_thenException () {Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = Collections2.filter (imena, predikati.contensPattern ("a")); result.add ("elvis"); }
3. Napišite prilagođeni filtar Predikat
Dalje - napišimo svoje Predikat umjesto da koristi onaj koji nudi knjižnica. U sljedećem primjeru - definirat ćemo predikat koji dobiva samo imena koja počinju s "A" ili "J":
@Test public void whenFilterCollectionWithCustomPredicate_thenFiltered () {Predikat predikata = novi predikat () {@Override public boolean apply (String input) return input.startsWith ("A")}; Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = Collections2.filter (imena, predikat); assertEquals (3, result.size ()); assertThat (rezultat, sadržiInAnyOrder ("John", "Jane", "Adam")); }
4. Kombinirajte više predikata
Možemo kombinirati više predikata koristeći Predikati.ili () i Predikati.i ().
U sljedećem primjeru - filtriramo a Popis imena da biste dobili imena koja počinju s "J" ili ne sadrže "a":
@Test public void whenFilterUsingMultiplePredicates_thenFiltered () {Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = Collections2.filter (imena, predikati.ili (predikati.containsPattern ("J"), predikati.not (Predicates.containsPattern ("a")))); assertEquals (3, result.size ()); assertThat (rezultat, sadržiInAnyOrder ("John", "Jane", "Tom")); }
5. Uklonite null vrijednosti tijekom filtriranja zbirke
Možemo očistiti null vrijednosti iz zbirke filtriranjem sa Predikati.notNull () kao u sljedećem primjeru:
@Test public void whenRemoveNullFromCollection_thenRemoved () {Imena popisa = Lists.newArrayList ("John", null, "Jane", null, "Adam", "Tom"); Rezultat zbirke = Collections2.filter (imena, predikati.notNull ()); assertEquals (4, result.size ()); assertThat (rezultat, sadržiInAnyOrder ("John", "Jane", "Adam", "Tom")); }
6. Provjerite podudaraju li se svi elementi u zbirci s uvjetima
Dalje, provjerimo odgovaraju li svi elementi u Zbirci određenom stanju. Koristit ćemo Iterables.all () da provjerimo sadrže li sva imena "n" ili "m", provjerit ćemo sadrže li svi elementi "a":
@Test public void whenCheckingIfAllElementsMatchACondition_thenCorrect () m ")); assertTrue (result); result = Iterables.all (names, Predicates.containsPattern (" a ")); assertFalse (rezultat);
7. Pretvorite zbirku
Sad - da vidimo kako transformirati kolekciju pomoću Guave Funkcija. U sljedećem primjeru - transformiramo a Popis imena na a Popis od Cijeli brojevi (duljina imena) sa Iterables.transform ():
@Test public void whenTransformWithIterables_thenTransformed () {Function function = new Function () {@Override public Integer apply (String input) {return input.length (); }}; Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Iterable rezultat = Iterables.transform (imena, funkcija); assertThat (rezultat, sadrži (4, 4, 4, 3)); }
Također možemo koristiti Collections2.transform () API kao u sljedećem primjeru:
@Test public void whenTransformWithCollections2_thenTransformed () {Function func = new Function () {@Preuzmi javni cjeloviti broj (String input) {return input.length (); }}; Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = Collections2.transform (imena, funkcija); assertEquals (4, result.size ()); assertThat (rezultat, sadrži (4, 4, 4, 3)); result.remove (3); assertEquals (3, names.size ()); }
Imajte na umu da je izlaz Collections.transform () je pogled uživo na izvornik Kolekcija- promjene jednih utječu na druge.
I - isto kao i prije - ako pokušamo dodati element na izlaz Kolekcija, an UnsupportedOperationException bit će bačen.
8. Stvorite Funkcija iz Predikat
Možemo i stvarati Funkcija od Predikat koristeći Functions.fromPredicate (). Ovo će, naravno, biti funkcija koja transformira ulaze Booleova, prema stanju predikata.
U sljedećem primjeru transformiramo a Popis imena na popis logičkih vrijednosti gdje svaki element predstavlja ako ime sadrži "m":
@Test public void whenCreatingAFunctionFromAPredicate_thenCorrect () {Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = Collections2.transform (imena, Funkcije.forPredicate (Predicate.containsPattern ("m"))); assertEquals (4, result.size ()); assertThat (rezultat, sadrži (false, false, true, true)); }
9. Sastav dviju funkcija
Dalje - pogledajmo kako transformirati Zbirku pomoću komponiranog Funkcija.
Funkcije.compose () vraća Sastav dviju funkcija jer primjenjuje drugu Funkcija na izlazu prvog Funkcija.
U sljedećem primjeru - prvi Funkcija transformirati ime u njegovu duljinu, a zatim drugu Funkcija pretvara duljinu u a boolean vrijednost koja predstavlja je li duljina imena parna:
@Test public void whenTransformingUsingComposedFunction_thenTransformed () {Funkcija f1 = nova funkcija () {@Preuzmi javni cjeloviti broj (String input) {return input.length (); }}; Funkcija f2 = nova funkcija () {@Premjesti javnu logičku primjenu (Integer input) {return input% 2 == 0; }}; Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = Collections2.transform (imena, funkcije.compose (f2, f1)); assertEquals (4, result.size ()); assertThat (rezultat, sadrži (true, true, true, false)); }
10. Kombinirajte filtriranje i pretvaranje
A sada - da vidimo još jedan kul API koji Guava ima - onaj koji će nam zapravo omogućiti zajedničko filtriranje i transformiranje - TečnoIterabilno.
U sljedećem primjeru - filtriramo Popis imena zatim ga transformirati pomoću TečnoIterabilno:
@Test public void whenFilteringAndTransformingCollection_thenCorrect () {Predikat predikata = novi predikat () {@Preuzmi javnu logičku primjenu (unos niza)}; Funkcija func = nova funkcija () {@Preuzmi javni cijeli broj (primijeni niz) {return input.length (); }}; Imena popisa = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Rezultat zbirke = FluentIterable.from (imena) .filter (predikat) .transform (func) .toList (); assertEquals (2, result.size ()); assertThat (rezultat, sadržiInAnyOrder (4, 3)); }
Vrijedno je spomenuti da je, u nekim slučajevima, imperativna verzija čitljivija i treba joj dati prednost u odnosu na funkcionalni pristup.
11. Zaključak
Na kraju smo naučili kako filtrirati i transformirati zbirke pomoću Guave. Koristili smo Collections2.filter () i Iterables.filter () API-ji za filtriranje, kao i Collections2.transform () i Iterables.transform () transformirati zbirke.
Na kraju smo na brzinu pogledali vrlo zanimljivo TečnoIterabilno tečni API za kombiniranje filtriranja i transformiranja.
Implementacija svih ovih primjera i isječaka koda možete pronaći u projektu GitHub - ovo je projekt zasnovan na Mavenu, pa bi ga trebalo biti lako uvesti i pokrenuti kakav jest.