Collecties filteren en transformeren in Guava

1. Overzicht

In deze tutorial laten we zien hoe filter en transformeer collecties met Guava.

We filteren met predikaten, transformeren met behulp van de functies die de bibliotheek biedt en tot slot zullen we zien hoe we zowel filteren als transformeren kunnen combineren.

2. Filter een collectie

Laten we beginnen met een eenvoudig voorbeeld van een collectie filteren. We zullen een kant-en-klaar predikaat gebruiken dat door de bibliotheek wordt geleverd en is gemaakt via het Predikaten hulpprogramma klasse:

@Test public void whenFilterWithIterables_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Herhaalbaar resultaat = Iterables.filter (namen, Predicates.containsPattern ("a")); assertThat (resultaat, bevatInAnyOrder ("Jane", "Adam")); }

Zoals u kunt zien, filteren we de Lijst van namen om alleen de namen te krijgen die het teken "a" bevatten - en we gebruiken Iterables.filter () om het te doen.

Als alternatief kunnen we er goed gebruik van maken Collections2.filter () API ook:

@Test public void whenFilterWithCollections2_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Verzamelingsresultaat = Collections2.filter (namen, Predicates.containsPattern ("a")); assertEquals (2, result.size ()); assertThat (resultaat, bevatInAnyOrder ("Jane", "Adam")); result.add ("anna"); assertEquals (5, names.size ()); }

Een paar dingen om op te merken - ten eerste, de uitvoer van Collections.filter () is een live weergave van de originele collectie - wijzigingen in de ene worden weerspiegeld in de andere.

Het is ook belangrijk om te begrijpen dat nu, het resultaat wordt beperkt door het predikaat - als we een element toevoegen dat daar niet aan voldoet Predikaat, een IllegalArgumentException zal worden gegooid:

@Test (verwacht = IllegalArgumentException.class) public void givenFilteredCollection_whenAddingInvalidElement_thenException () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Verzamelingsresultaat = Collections2.filter (namen, Predicates.containsPattern ("a")); result.add ("elvis"); }

3. Schrijf een aangepast filter Predikaat

Vervolgens - laten we onze eigen schrijven Predikaat in plaats van er een te gebruiken die door de bibliotheek wordt verstrekt. In het volgende voorbeeld zullen we een predikaat definiëren dat alleen de namen krijgt die beginnen met "A" of "J":

@Test public void whenFilterCollectionWithCustomPredicate_thenFiltered () {Predicaat predicaat = nieuw predicaat () {@Override public boolean apply (String input) return input.startsWith ("A")}; List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Collectieresultaat = Collections2.filter (namen, predikaat); assertEquals (3, result.size ()); assertThat (resultaat, bevatInAnyOrder ("John", "Jane", "Adam")); }

4. Combineer meerdere predikaten

We kunnen meerdere predikaten combineren met Predikaten. Of () en Predikaten. En ().

In het volgende voorbeeld filteren we een Lijst van namen om de namen te krijgen die beginnen met "J" of die geen "a" bevatten:

@Test public void whenFilterUsingMultiplePredicates_thenFiltered () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Verzamelingsresultaat = Collections2.filter (names, Predicates.or (Predicates.containsPattern ("J"), Predicates.not (Predicates.containsPattern ("a")))); assertEquals (3, result.size ()); assertThat (resultaat, bevatInAnyOrder ("John", "Jane", "Tom")); }

5. Null-waarden verwijderen tijdens het filteren van een collectie

We kunnen de nul waarden uit een verzameling door deze te filteren met Predicates.notNull () zoals in het volgende voorbeeld:

@Test public void whenRemoveNullFromCollection_thenRemoved () {List names = Lists.newArrayList ("John", null, "Jane", null, "Adam", "Tom"); Verzamelingsresultaat = Collections2.filter (names, Predicates.notNull ()); assertEquals (4, result.size ()); assertThat (resultaat, bevatInAnyOrder ("John", "Jane", "Adam", "Tom")); }

6. Controleer of alle elementen in een collectie overeenkomen met een voorwaarde

Laten we vervolgens kijken of alle elementen in een collectie aan een bepaalde voorwaarde voldoen. We zullen gebruiken Iterables.all () om te controleren of alle namen "n" of "m" bevatten, dan zullen we controleren of alle elementen "a" bevatten:

@Test public void whenCheckingIfAllElementsMatchACondition_thenCorrect () m ")); assertTrue (resultaat); resultaat = Iterables.all (namen, Predicates.containsPattern (" a ")); assertFalse (resultaat); 

7. Transformeer een collectie

Laten we nu eens kijken hoe transformeer een collectie met behulp van een Guava Functie. In het volgende voorbeeld transformeren we a Lijst van namen naar een Lijst van Gehele getallen (lengte van de naam) met Iterables.transform ():

@Test public void whenTransformWithIterables_thenTransformed () {Function function = new Function () {@Override public Integer apply (String input) {return input.length (); }}; List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Herhaalbaar resultaat = Iterables.transform (namen, functie); assertThat (resultaat, bevat (4, 4, 4, 3)); }

We kunnen ook de Collections2.transform () API zoals in het volgende voorbeeld:

@Test public void whenTransformWithCollections2_thenTransformed () {Function func = new Function () {@Override public Integer apply (String input) {return input.length (); }}; List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Collectieresultaat = Collections2.transform (names, func); assertEquals (4, result.size ()); assertThat (resultaat, bevat (4, 4, 4, 3)); result.remove (3); assertEquals (3, names.size ()); }

Merk op dat de output van Collections.transform () is een live weergave van het origineel Verzameling- veranderingen in de ene beïnvloeden de andere.

En - hetzelfde als voorheen - als we proberen een element aan de uitvoer toe te voegen Verzameling, een UnsupportedOperationException zal worden gegooid.

8. Creëer Functie van Predikaat

We kunnen ook creëren Functie van een Predikaat gebruik makend van Functions.fromPredicate (). Dit wordt natuurlijk een functie die de invoer transformeert naar Boolean, volgens de conditie van het predikaat.

In het volgende voorbeeld transformeren we een Lijst van namen naar een lijst met booleans waarbij elk element vertegenwoordigt of de naam "m" bevat:

@Test public void whenCreatingAFunctionFromAPredicate_thenCorrect () {List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Verzamelingsresultaat = Collections2.transform (namen, Functions.forPredicate (Predicates.containsPattern ("m"))); assertEquals (4, result.size ()); assertThat (resultaat, bevat (false, false, true, true)); }

9. Samenstelling van twee functies

Laten we nu eens kijken hoe we een collectie kunnen transformeren met een samengesteld Functie.

Functions.compose () geeft de samenstelling van twee functies terug zoals het de tweede toepast Functie op de output van de eerste Functie.

In het volgende voorbeeld - het eerste Functie transformeer de naam in zijn lengte, dan de tweede Functie transformeert de lengte naar een boolean waarde die aangeeft of de lengte van de naam even is:

@Test openbare leegte whenTransformingUsingComposedFunction_thenTransformed () {Functie f1 = nieuwe functie () {@Override openbaar geheel getal van toepassing (String-invoer) {return input.length (); }}; Functie f2 = nieuwe functie () {@Override public Boolean apply (Integer input) {return input% 2 == 0; }}; List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Collectieresultaat = Collections2.transform (names, Functions.compose (f2, f1)); assertEquals (4, result.size ()); assertThat (resultaat, bevat (true, true, true, false)); }

10. Combineer filteren en transformeren

En nu - laten we eens kijken naar een andere coole API die Guava heeft - een waarmee we filteren en transformeren samen kunnen koppelen - de Vloeiend.

In het volgende voorbeeld filteren we de Lijst van namen transformeren het vervolgens met Vloeiend:

@Test public void whenFilteringAndTransformingCollection_thenCorrect () {Predicaat predicaat = nieuw predicaat () {@Override public boolean apply (String input)}; Function func = new Function () {@Override public Integer apply (String input) {return input.length (); }}; List names = Lists.newArrayList ("John", "Jane", "Adam", "Tom"); Verzamelingsresultaat = FluentIterable.from (namen) .filter (predikaat) .transform (func) .toList (); assertEquals (2, result.size ()); assertThat (resultaat, bevatInAnyOrder (4, 3)); }

Het is vermeldenswaard dat in sommige gevallen de imperatieve versie beter leesbaar is en de voorkeur verdient boven de functionele benadering.

11. Conclusie

Ten slotte hebben we geleerd hoe we collecties kunnen filteren en transformeren met Guava. We gebruikten de Collections2.filter () en Iterables.filter () API's voor filteren, evenals Collections2.transform () en Iterables.transform () om collecties te transformeren.

Ten slotte hebben we snel gekeken naar het zeer interessante Vloeiend vloeiende API om zowel filteren als transformeren te combineren.

De implementatie van al deze voorbeelden en codefragmenten is te vinden in het GitHub-project - dit is een op Maven gebaseerd project, dus het zou gemakkelijk moeten kunnen worden geïmporteerd en uitgevoerd zoals het is.


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