Wie erhalte ich das umgekehrte Resultat für einen Java Streams Filter?

Java Streams sind eine feine Sache. Ich habe das Gefühl, ich fange mittlerweile alle meine Java Beiträge mit diesem Satz an. 🙂

Ein Java Streams Filter erlaubt es einem, auf einfache Weise alle gewünschten Einträge aus einer Liste herauszufiltern und den Rest wegzuschmeissen. Alle roten Elefanten, alle Kinder unter 6 Jahren, alle Schlangen mit Flügeln und so weiter.

Oftmals ist es aber einfacher zu sagen, was man nicht will. Als quasi ‚Schau her, ich selektiere alle Kinder zwischen 5 und 8 Jahren… und jetzt, du superkluges Java, gib mir alle anderen Kinder!

Wie macht man das?

Not Predicate definieren

Ganz einfach: Wo auch immer man den Filter umgekehren will definiert man ein Not Predicate. Predicate ist ja dieses Dings in dem Filter, und wenn das „true“ ist, wird der jeweilige Eintrag behalten. Und mit einem Not Predicate drehen wir die Logik einfach um.

Folgenden Code irgendwo hinschmeissen:

public static <T> Predicate<T> not(Predicate<T> t) {
    return t.negate();
}

Und dann kann man das not im Filter verwenden.

Beispiel: Ihr habt eine Liste mit Kindernamen und findet den Namen „Rupert“ einfach wiederlich, den wollt Ihr unbedingt losweren. Also definieren wir zuerst einen Filter für den Namen ‚Rupert‘:

Arrays.stream(kindernamen).filter(kindername -> kindername.contains("Rupert")).collect(Collectors.toList());

Dieser Filter würde jetzt also alle Ruperts in der Resultateliste haben.

Dann kehren wir den Filter einfach um:

Arrays.stream(kindernamen).filter(not(kindername -> kindername.contains("Rupert"))).collect(Collectors.toList());

Et voilà.

Java 11 hats schon drin

Kleine Randbemerkung: In Java 11 ist genau diese Methode beim Predicate schon dabei:

Predicate.not( … )

Siehe https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/function/Predicate.html#not(java.util.function.Predicate)

Dann geht unser Rupert-Hass-Filter folgendermassen (und das Predicate muss man natürlich nicht mehr selber definieren):

Arrays.stream(kindernamen).filter(Predicate.not(kindername -> kindername.contains("Rupert"))).collect(Collectors.toList());

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

WordPress.com-Logo

Du kommentierst mit deinem WordPress.com-Konto. Abmelden /  Ändern )

Facebook-Foto

Du kommentierst mit deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s