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); }

18voto

Askar Kalykov Punkte 2457

Eine weitere Möglichkeit besteht darin, Lambda-Casting in nicht eindeutigen Kontexten in eine Klasse zu verwenden:

public static class Lambdas {
    public static  Predicate as(Predicate predicate){
        return predicate;
    }

    public static  Consumer as(Consumer consumer){
        return consumer;
    }

    public static  Supplier as(Supplier supplier){
        return supplier;
    }

    public static  Function as(Function function){
        return function;
    }

}

... und dann die Utility-Klasse statisch importieren:

stream.filter(as(String::isEmpty).negate())

11voto

Marco13 Punkte 52276

Sollte nicht Predicate#negate das sein, wonach du suchst?

10voto

outofBounds Punkte 585

In diesem Fall könnten Sie das org.apache.commons.lang3.StringUtils verwenden und tun

int nonEmptyStrings = s.filter(StringUtils::isNotEmpty).count();

4voto

Per-Åke Minborg Punkte 290

Ich habe eine vollständige Hilfsklasse geschrieben (basierend auf Askars Vorschlag), die Java 8 Lambda-Ausdrücke entgegennehmen und sie (falls zutreffend) in jede typisierte Standard-Java-8-Lambda im Paket java.util.function umwandeln kann. Du kannst zum Beispiel Folgendes tun:

  • asPredicate(String::isEmpty).negate()
  • asBiPredicate(String::equals).negate()

Weil es zahlreiche Zweideutigkeiten geben würde, wenn alle statischen Methoden einfach nur as() genannt würden, habe ich mich dafür entschieden, die Methode "as" gefolgt vom zurückgegebenen Typ zu nennen. Dies gibt uns volle Kontrolle über die Lambda-Interpretation. Nachfolgend ist der erste Teil der (etwas umfangreichen) Hilfsklasse zu sehen, die das verwendete Muster zeigt.

Schau dir die komplette Klasse hier (bei Gist) an.

public class FunctionCastUtil {

    public static  BiConsumer asBiConsumer(BiConsumer biConsumer) {
        return biConsumer;
    }

    public static  BiFunction asBiFunction(BiFunction biFunction) {
        return biFunction;
    }

     public static  BinaryOperator asBinaryOperator(BinaryOperator binaryOperator) {
        return binaryOperator;
    }

    ... und so weiter...
}

4voto

Nikhil Nanivadekar Punkte 1132

Sie können Predicates von Eclipse Collections verwenden

MutableList strings = Lists.mutable.empty();
int nonEmptyStrings = strings.count(Predicates.not(String::isEmpty));

Wenn Sie die strings nicht von List ändern können:

List strings = new ArrayList<>();
int nonEmptyStrings = ListAdapter.adapt(strings).count(Predicates.not(String::isEmpty));

Wenn Sie nur eine Negation von String.isEmpty() benötigen, können Sie auch StringPredicates.notEmpty() verwenden.

Hinweis: Ich bin ein Contributor zu Eclipse Collections.

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