So filtern Sie eine Collection in Java

So filtern Sie eine Sammlung in Java

1. Überblick

In diesem kurzen Tutorial werdenwe’ll have a look at different ways of filtering a Collection in Java - das heißt, 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 9filtering Kollektor

  • RelevanteEclipse Collections APIs

  • ApachesCollectionUtils filter()-Methode

  • GuavasCollections2 filter()-Ansatz

2. Streams verwenden

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

Dies ist daher 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 mitStreams

Der Einfachheit halber sindin all the examples our objective will be to create a method that retrieves only the even numbers from a Collection vonInteger Werten.

Auf diese Weise können wir die Bedingung ausdrücken, die wir zur Bewertung jedes Elements als "value % 2 == 0" verwenden.

In allen Fällen müssen wir diese Bedingung alsPredicate-Objekt 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, dasseach library we analyze in this tutorial provides its own Predicate implementation, aber dennoch alle als funktionale Schnittstellen definiert sind, sodass wir Lambda-Funktionen verwenden können, um sie zu deklarieren.

In diesem Fall haben wir ein von Java bereitgestelltes vordefiniertesCollector verwendet, das die Elemente inList akkumuliert, aber wir hätten auch andere verwenden können, wie inthis previous post beschrieben.

2.2. Filtern nach Gruppierung einer Sammlung in Java 9

Mit Streams können wir Elemente mitgroupingBy collector aggregieren.

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

Aus diesem Grund istthe filtering collector was introduced with Java 9, with the objective of processing the subcollections after they have been grouped.

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 vonEclipse Collections

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 beiEclipse 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 damit beginnen, unsereEclipse Collections Introductory postzu untersuchen, um ein breiteres Wissen über die von dieser Bibliothek bereitgestellten Funktionen zu erhalten.

3.1. Abhängigkeiten

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


    org.eclipse.collections
    eclipse-collections
    9.2.0

Daseclipse-collections enthält alle erforderlichen Datenstrukturschnittstellen und die API selbst.

3.2. Filtern einer Sammlung mitEclipse Collections

Verwenden wir jetzt die Filterfunktion von eclipse für eine seiner Datenstrukturen, z. B.MutableList:

public Collection findEvenNumbers(Collection baseCollection) {
    Predicate eclipsePredicate
      = item -> item % 2 == 0;

    Collection filteredList = Lists.mutable
      .ofAll(baseCollection)
      .select(eclipsePredicate);

    return filteredList;
}

Alternativ könnten wir dieselect() static-Methode vonIterateverwenden, um dasfilteredList-Objekt zu definieren:

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

4. Verwenden von ApachesCollectionUtils

Um mit derCollectionUtils-Bibliothek von Apache zu beginnen, können Siethis short tutorial überprüfen, in denen wir deren 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 unsererpom.xml-Datei:


    org.apache.commons
    commons-collections4
    4.2

4.2. Filtern einer Sammlung mitCollectionUtils

Wir sind jetzt bereit, die Methoden vonCollectonUtilszu verwenden:

public Collection findEvenNumbers(Collection baseCollection) {
    Predicate apachePredicate = item -> item % 2 == 0;

    CollectionUtils.filter(baseCollection, apachePredicate);
    return baseCollection;
}

Wir müssen berücksichtigen, dass diese Methode diebaseCollection ändert, indem jedes Element entfernt wird, das nicht der Bedingung entspricht.

Dies bedeutet, dassthe base Collection has to be mutable, otherwise it will throw an exception.

5. Verwenden von GuavasCollections2

Nach wie vor können wir unseren vorherigen Beitrag‘Filtering and Transforming Collections in Guava' lesen, um weitere Informationen zu diesem Thema zu erhalten.

5.1. Abhängigkeiten

Beginnen wir mit dem Hinzufügen vonthis dependency in unsererpom.xml-Datei:


    com.google.guava
    guava
    25.1-jre

5.2. Filtern einer Sammlung mitCollections2

Wie wir sehen können, ist dieser Ansatz dem im letzten Abschnitt verfolgten ziemlich ähnlich:

public Collection findEvenNumbers(Collection baseCollection) {
    Predicate guavaPredicate = item -> item % 2 == 0;

    return Collections2.filter(baseCollection, guavaPredicate);
}

Auch hier definieren wir ein Guava-spezifischesPredicate-Objekt.

In diesem Fall ändert Guava diebaseCollection nicht, sondern generiert eine neue, sodass wir eine unveränderliche Sammlung als Eingabe verwenden können.

6. Fazit

Zusammenfassend haben wir gesehen, dass es in Java viele verschiedene Möglichkeiten gibt, Sammlungen zu filtern.

Obwohl Streams normalerweise der bevorzugte Ansatz sind, ist es gut, die Funktionen anderer Bibliotheken zu kennen und zu berücksichtigen.

Vor allem, wenn wir ältere Java-Versionen unterstützen müssen. In diesem Fall müssen wir jedoch die neuesten Java-Funktionen berücksichtigen, die im gesamten Lernprogramm verwendet werden, z. B., dass Lambdas durch anonyme Klassen ersetzt werden sollten.

Wie üblich finden wir alle in diesem Tutorial gezeigten Beispiele in unserenGithub repo.