So filtern Sie eine Sammlung in Java

1. Übersicht

In diesem kurzen Tutorial werden verschiedene Möglichkeiten zum Filtern einer Sammlung in Java vorgestellt , dh alle Elemente gefunden, die eine bestimmte Bedingung erfüllen.

Dies ist eine grundlegende Aufgabe, die in praktisch jeder Java-Anwendung vorhanden ist.

Aus diesem Grund ist die Anzahl der Bibliotheken, die Funktionen für diesen Zweck bereitstellen, erheblich.

In diesem Tutorial werden wir insbesondere Folgendes behandeln:

  • Filter () -Funktion von Java 8 Streams
  • Java 9 Filterungs Kollektors
  • Relevante Eclipse Collections- APIs
  • Apaches CollectionUtils filter () -Methode
  • Guavas Collections2 filter () -Ansatz

2. Verwenden von Streams

Seit der Einführung von Java 8 haben Streams in den meisten Fällen, in denen wir eine Datenerfassung verarbeiten müssen, eine Schlüsselrolle übernommen.

Folglich ist dies in den meisten Fällen der bevorzugte Ansatz, da er in Java erstellt wurde und keine zusätzlichen Abhängigkeiten erfordert.

2.1. Filtern einer Sammlung mit Streams

Aus Gründen der Einfachheit in allen Beispielen wird unser Ziel , ein Verfahren , dass abruft nur die geraden Zahlen von einem erstellen seine Sammlung von Integer - Werten.

Somit können wir die Bedingung, mit der wir jedes Element bewerten, als ' Wert% 2 == 0 ' ausdrücken .

In allen Fällen müssen wir diese Bedingung als Prädikatobjekt definieren :

public Collection findEvenNumbers(Collection baseCollection) { Predicate streamsPredicate = item -> item % 2 == 0; return baseCollection.stream() .filter(streamsPredicate) .collect(Collectors.toList()); }

Es ist wichtig zu beachten, dass jede Bibliothek, die wir in diesem Tutorial analysieren, eine eigene Predicate- Implementierung bietet. Dennoch sind alle als funktionale Schnittstellen definiert, sodass wir Lambda-Funktionen verwenden können, um sie zu deklarieren.

In diesem Fall haben wir einen von Java bereitgestellten vordefinierten Collector verwendet , der die Elemente in einer Liste zusammenfasst . Wir hätten jedoch auch andere verwenden können, wie in diesem vorherigen Beitrag erläutert.

2.2. Filtern nach dem Gruppieren einer Sammlung in Java 9

Mit Streams können wir Elemente mithilfe des groupingBy-Kollektors aggregieren .

Wenn wir jedoch wie im letzten Abschnitt filtern, werden einige Elemente möglicherweise frühzeitig verworfen, bevor dieser Sammler ins Spiel kommt.

Aus diesem Grund wurde der Filterkollektor mit Java 9 eingeführt, um die Untersammlungen nach ihrer Gruppierung zu verarbeiten.

Stellen Sie sich nach unserem Beispiel vor, wir möchten unsere Sammlung anhand der Anzahl der Ziffern jeder Ganzzahl gruppieren, bevor wir die ungeraden Zahlen herausfiltern:

public Map
    
      findEvenNumbersAfterGrouping( Collection baseCollection) { Function getQuantityOfDigits = item -> (int) Math.log10(item) + 1; return baseCollection.stream() .collect(groupingBy( getQuantityOfDigits, filtering(item -> item % 2 == 0, toList()))); }
    

Kurz gesagt, wenn wir diesen Kollektor verwenden, erhalten wir möglicherweise einen leeren Werteintrag, während der Kollektor einen solchen Eintrag überhaupt nicht erstellen würde, wenn wir vor dem Gruppieren filtern.

Natürlich würden wir den Ansatz basierend auf unseren Anforderungen wählen.

3. Verwenden von Eclipse-Sammlungen

Wir können auch einige andere Bibliotheken von Drittanbietern verwenden, um unser Ziel zu erreichen, entweder weil unsere Anwendung Java 8 nicht unterstützt oder weil wir einige leistungsstarke Funktionen nutzen möchten, die nicht von Java bereitgestellt werden.

Dies ist der Fall bei Eclipse Collections , einer Bibliothek, die sich bemüht, mit den neuen Paradigmen Schritt zu halten und die Änderungen, die durch die neuesten Java-Versionen eingeführt wurden, weiterzuentwickeln und zu berücksichtigen.

Wir können zunächst unseren Einführungsbeitrag zu Eclipse-Sammlungen lesen, um ein umfassenderes Wissen über die von dieser Bibliothek bereitgestellten Funktionen zu erhalten.

3.1. Abhängigkeiten

Beginnen wir mit dem Hinzufügen der folgenden Abhängigkeit zur pom.xml unseres Projekts :

 org.eclipse.collections eclipse-collections 9.2.0 

Die Eclipse-Sammlungen enthalten alle erforderlichen Datenstrukturschnittstellen und die API selbst.

3.2. Filtern einer Sammlung mit Eclipse-Sammlungen

Lassen Sie uns nun die Filterfunktion von eclipse für eine seiner Datenstrukturen verwenden, z. B. für die MutableList :

public Collection findEvenNumbers(Collection baseCollection) { Predicate eclipsePredicate = item -> item % 2 == 0; Collection filteredList = Lists.mutable .ofAll(baseCollection) .select(eclipsePredicate); return filteredList; }

Als Alternative haben wir die verwendet werden könnten , Iterate ‚s select ()statische Methode zum Definieren des gefilterten Listenobjekts:

Collection filteredList = Iterate.select(baseCollection, eclipsePredicate);

4. Verwenden der CollectionUtils von Apache

Um mit der CollectionUtils- Bibliothek von Apache zu beginnen , können Sie dieses kurze Tutorial lesen, in dem wir seine Verwendung behandelt haben.

In diesem Tutorial konzentrieren wir uns jedoch auf die Implementierung von filter () .

4.1. Abhängigkeiten

Zunächst benötigen wir die folgenden Abhängigkeiten in unserer Datei pom.xml :

 org.apache.commons commons-collections4 4.2 

4.2. Filtering a Collection with CollectionUtils

We are now ready to use the CollectonUtils‘ methods:

public Collection findEvenNumbers(Collection baseCollection) { Predicate apachePredicate = item -> item % 2 == 0; CollectionUtils.filter(baseCollection, apachePredicate); return baseCollection; }

We have to take into account that this method modifies the baseCollection by removing every item that doesn't match the condition.

This means that the base Collection has to be mutable, otherwise it will throw an exception.

5. Using Guava's Collections2

As before, we can read our previous post ‘Filtering and Transforming Collections in Guava' for further information on this subject.

5.1. Dependencies

Let's start by adding this dependency in our pom.xml file:

 com.google.guava guava 25.1-jre 

5.2. Filtering a Collection with Collections2

As we can see, this approach is fairly similar to the one followed in the last section:

public Collection findEvenNumbers(Collection baseCollection) { Predicate guavaPredicate = item -> item % 2 == 0; return Collections2.filter(baseCollection, guavaPredicate); }

Again, here we define a Guava specific Predicate object.

In this case, Guava doesn't modify the baseCollection, it generates a new one, so we can use an immutable collection as input.

6. Conclusion

In summary, we've seen that there are many different ways of filtering collections in Java.

Even though Streams are usually the preferred approach, its good to know and keep in mind the functionality offered by other libraries.

Especially if we need to support older Java versions. However, if this is the case, we need to keep in mind recent Java features used throughout the tutorial such as lambdas should be replaced with anonymous classes.

Wie üblich finden wir alle in diesem Tutorial gezeigten Beispiele in unserem Github-Repo.