Hoe een collectie in Java te filteren

1. Overzicht

In deze korte tutorial, we zullen verschillende manieren bekijken om een ​​collectie in Java te filteren - dat wil zeggen, het vinden van alle items die aan een bepaalde voorwaarde voldoen.

Dit is een fundamentele taak die in praktisch elke Java-applicatie aanwezig is.

Om deze reden is het aantal bibliotheken dat functionaliteit biedt voor dit doel aanzienlijk.

In deze tutorial behandelen we met name:

  • Java 8-streams ' filter() functie
  • Java 9 filteren verzamelaar
  • Relevant Eclipse-collecties API's
  • Apache's CollectionUtils filter () methode
  • Guava's Collecties2 filter () nadering

2. Streams gebruiken

Sinds de introductie van Java 8 hebben Streams een sleutelrol gekregen in de meeste gevallen waarin we een verzameling gegevens moeten verwerken.

Daarom heeft dit in de meeste gevallen de voorkeur, aangezien het in Java is gebouwd en geen extra afhankelijkheden vereist.

2.1. Een collectie filteren met Streams

Om het simpel te houden, in alle voorbeelden is ons doel om een ​​methode te creëren die alleen de even getallen ophaalt uit een Verzameling van Geheel getal waarden.

We kunnen dus de voorwaarde die we gebruiken om elk item te evalueren, uitdrukken als ‘waarde% 2 == 0‘.

In alle gevallen zullen we deze voorwaarde moeten definiëren als een Predikaat voorwerp:

openbare verzameling findEvenNumbers (verzameling baseCollection) {Predicaat streamsPredicate = item -> item% 2 == 0; return baseCollection.stream () .filter (streamsPredicate) .collect (Collectors.toList ()); }

Het is belangrijk om dat op te merken elke bibliotheek die we in deze tutorial analyseren, biedt zijn eigen bibliotheek Predikaat implementatie, maar toch, ze zijn allemaal gedefinieerd als functionele interfaces, waardoor we Lambda-functies kunnen gebruiken om ze te declareren.

In dit geval hebben we een voorgedefinieerd Verzamelaar geleverd door Java die de elementen verzamelt in een Lijst, maar we hadden andere kunnen gebruiken, zoals besproken in dit vorige bericht.

2.2. Filteren na het groeperen van een collectie in Java 9

Met streams kunnen we items samenvoegen met behulp van de groupingBy collector.

Maar als we filteren zoals we in de vorige sectie hebben gedaan, kunnen sommige elementen in een vroeg stadium worden weggegooid, voordat deze verzamelaar in het spel komt.

Om deze reden, de filteren collector is geïntroduceerd met Java 9, met als doel de subcollecties te verwerken nadat ze zijn gegroepeerd.

Laten we ons voorbeeld volgen en laten we ons voorstellen dat we onze verzameling willen groeperen op basis van het aantal cijfers dat elk geheel getal heeft, voordat we de oneven getallen eruit filteren:

openbare kaart findEvenNumbersAfterGrouping (Collectie baseCollection) {Functie getQuantityOfDigits = item -> (int) Math.log10 (item) + 1; return baseCollection.stream () .collect (groupingBy (getQuantityOfDigits, filtering (item -> item% 2 == 0, toList ()))); }

Kortom, als we deze verzamelaar gebruiken, kunnen we eindigen met een lege waarde-invoer, terwijl als we filteren voordat we groeperen, de verzamelaar een dergelijke invoer helemaal niet zou maken.

Natuurlijk zouden we de aanpak kiezen op basis van onze vereisten.

3. Met behulp van Eclipse-collecties

We kunnen ook gebruik maken van enkele andere bibliotheken van derden om ons doel te bereiken, hetzij omdat onze applicatie Java 8 niet ondersteunt, hetzij omdat we willen profiteren van een aantal krachtige functionaliteit die niet door Java wordt geleverd.

Dat is het geval bij Eclipse-collecties, een bibliotheek die ernaar streeft gelijke tred te houden met de nieuwe paradigma's, evolueert en de veranderingen omarmt die door de nieuwste Java-releases zijn geïntroduceerd.

We kunnen beginnen met het verkennen van onze Eclipse Collections-inleidende post om een ​​bredere kennis te hebben van de functionaliteit die door deze bibliotheek wordt geboden.

3.1. Afhankelijkheden

Laten we beginnen met het toevoegen van de volgende afhankelijkheid aan ons project pom.xml:

 org.eclipse.collections eclipse-collections 9.2.0 

De eclipse-collecties bevat alle benodigde datastructuurinterfaces en de API zelf.

3.2. Een collectie filteren met Eclipse-collecties

Laten we nu de filterfunctionaliteit van eclipse gebruiken op een van zijn datastructuren, zoals zijn MutableList:

openbare verzameling findEvenNumbers (verzameling baseCollection) {Predicaat eclipsePredicate = item -> item% 2 == 0; Collectie filterList = Lists.mutable .ofAll (baseCollection) .select (eclipsePredicate); retourneer gefilterdeList; }

Als alternatief hadden we de Herhalen‘S selecteer ()statische methode om het gefilterde lijst voorwerp:

Collectie filterList = Iterate.select (baseCollection, eclipsePredicate);

4. Apache's gebruiken CollectionUtils

Om te beginnen met Apache's CollectionUtils bibliotheek, kunnen we deze korte tutorial bekijken waarin we het gebruik ervan hebben besproken.

In deze tutorial zullen we ons echter concentreren op zijn filter() implementatie.

4.1. Afhankelijkheden

Ten eerste hebben we de volgende afhankelijkheden nodig in onze pom.xml het dossier:

 org.apache.commons commons-collections4 4.2 

4.2. Een collectie filteren met CollectionUtils

We zijn nu klaar om het CollectonUtils‘Methoden:

openbare verzameling findEvenNumbers (verzameling baseCollection) {Predicaat apachePredicate = item -> item% 2 == 0; CollectionUtils.filter (baseCollection, apachePredicate); terugkeer baseCollection; }

We moeten er rekening mee houden dat deze methode de baseCollection door elk item te verwijderen dat niet aan de conditie voldoet.

Dit betekent dat de basiscollectie moet veranderbaar zijn, anders genereert het een uitzondering.

5. Guava's gebruiken Collecties 2

Net als eerder kunnen we ons vorige bericht ‘Collecties filteren en transformeren in Guava 'lezen voor meer informatie over dit onderwerp.

5.1. Afhankelijkheden

Laten we beginnen met het toevoegen van deze afhankelijkheid in onze pom.xml het dossier:

 com.google.guava guave 25.1-jre 

5.2. Een collectie filteren met Collecties 2

Zoals we kunnen zien, lijkt deze aanpak redelijk op die in de laatste sectie:

openbare verzameling findEvenNumbers (verzameling baseCollection) {Predicaat guavaPredicate = item -> item% 2 == 0; return Collections2.filter (baseCollection, guavaPredicate); }

Nogmaals, hier definiëren we een Guava-specifiek Predikaat voorwerp.

In dit geval wijzigt Guava de baseCollection, het genereert een nieuwe, dus we kunnen een onveranderlijke verzameling als invoer gebruiken.

6. Conclusie

Samenvattend hebben we gezien dat er veel verschillende manieren zijn om verzamelingen in Java te filteren.

Hoewel streams meestal de voorkeur genieten, is het goed om de functionaliteit van andere bibliotheken te kennen en in gedachten te houden.

Vooral als we oudere Java-versies moeten ondersteunen. Als dit echter het geval is, moeten we in gedachten houden dat recente Java-functies die in de tutorial worden gebruikt, zoals lambdas, moeten worden vervangen door anonieme klassen.

Zoals gewoonlijk kunnen we alle voorbeelden in deze tutorial vinden in onze Github-opslagplaats.