479 Stimmen

Wie man ein Methoden-Referenz-Predicate negiert

In Java 8 kannst du eine Methodenreferenz verwenden, um einen Stream zu filtern, zum Beispiel:

Stream s = ...;
long emptyStrings = s.filter(String::isEmpty).count();

Gibt es eine Möglichkeit, eine Methodenreferenz zu erstellen, die die Negation einer vorhandenen ist, also so etwas wie:

long nonEmptyStrings = s.filter(not(String::isEmpty)).count();

Ich könnte die not Methode wie unten erstellen, aber ich frage mich, ob die JDK etwas Ähnliches anbietet.

static  Predicate not(Predicate p) { return o -> !p.test(o); }

2voto

finjacore Punkte 71

Hinweis: Um ein collection.stream().anyMatch(...) zu negieren, kann man collection.stream().noneMatch(...) verwenden

1voto

Sie können dies erreichen, solange emptyStrings = s.filter(s->!s.isEmpty()).count();

0voto

Gilad Peleg Punkte 2010

Wenn Sie Spring Boot (2.0.0+) verwenden, können Sie verwenden:

import org.springframework.util.StringUtils;

...
.filter(StringUtils::hasLength)
...

Das bedeutet: return (str != null && !str.isEmpty());

Es wird also den erforderlichen Negationseffekt für isEmpty haben

0voto

TWiStErRob Punkte 41031

Da dies auch für Kotlin ("kotlin negate function reference") bei Google am höchsten eingestuft ist, werde ich hier eine Antwort posten:

import kotlin.reflect.KFunction1

/**
 * Kotlin-Version von [java.util.function.Predicate.negate] für funktionale Typen.
 *
 * Beispiel:
 * ```
 * val isX: X -> Boolean = ...
 * val isNotX = !isX
 * val isNotX = isX.not()
 * ```
 */
operator fun <T> ((T) -> Boolean).not(): (T) -> Boolean =
    { !this(it) }

/**
 * Kotlin-Version von [java.util.function.Predicate.negate] für Methodenreferenzen.
 *
 * Beispiel:
 * ```
 * fun isX(x: X): Boolean = ...
 * val isNotX = !::isX
 * ```
 */
operator fun <T> KFunction1<T, Boolean>.not(): KFunction1<T, Boolean> =
    { it: T -> !this(it) }::invoke

/**
 * Kotlin-Version von [java.util.function.Predicate.or] für funktionale Typen.
 */
infix fun <T> ((T) -> Boolean).or(other: (T) -> Boolean): (T) -> Boolean =
    { this(it) || other(it) }

/**
 * Kotlin-Version von [java.util.function.Predicate.or] für Methodenreferenzen.
 */
infix fun <T> KFunction1<T, Boolean>.or(other: KFunction1<T, Boolean>): KFunction1<T, Boolean> =
    { it: T -> this(it) || other(it) }::invoke

/**
 * Kotlin-Version von [java.util.function.Predicate.and] für funktionale Typen.
 */
infix fun <T> ((T) -> Boolean).and(other: (T) -> Boolean): (T) -> Boolean =
    { this(it) && other(it) }

/**
 * Kotlin-Version von [java.util.function.Predicate.and] für Methodenreferenzen.
 */
infix fun <T> KFunction1<T, Boolean>.and(other: KFunction1<T, Boolean>): KFunction1<T, Boolean> =
    { it: T -> this(it) && other(it) }::invoke

Ich bin mir nicht bewusst, dass diese in stdlib existieren, vielleicht gibt es sie bereits in einigen Bibliotheken. Hoffentlich hilft dies jemandem in der Zukunft, da die Syntax nicht trivial war.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X