如何否定 lambda 谓词?

How can I negate a lambda Predicate?

假设我有一个字符串流。

final Stream<String> stream = ...;

我想在修剪后过滤掉每个空字符串。

stream
    .filter(Objects::nonNull)
    .map(String::trim)
    .filter(v -> !v.isEmpty());

有什么方法可以申请 Predicate#negate() 替换 v -> !v.isEmpty() 部分吗?

.filter(((Predicate) String::isEmpty).negate()) // not compile

你必须做 .filter(((Predicate<String>) String::isEmpty).negate())

如果你愿意,你可以定义

static<T> Predicate<T> not(Predicate<T> p) {
    return t -> !p.test(t);
}

然后

.filter(not(String::isEmpty))

但我会坚持v -> !v.isEmpty()

看来你必须转换为 Predicate<String> 才能工作:

.filter(((Predicate<String>) (String::isEmpty)).negate())

当然,在这种情况下使用 lambda 会更短:

.filter(s -> ! s.isEmpty())

不用自己创建 类,而是使用 durian utility library. It has a lot of methodsandor 当然还有 not

import static com.diffplug.common.base.Predicates.not;

stream
.filter(Objects::nonNull)
.map(String::trim)
.filter(not(String::isEmpty));

从 java 11 开始,您可以使用 Predicate#not

import static java.util.function.Predicate.not;

stream
.filter(Objects::nonNull)
.map(String::trim)
.filter(not(String::isEmpty));