有一种方法可以组成与当前方法引用相反的方法引用。请参阅下面的@vlasec 的答案,该答案显示了如何将方法引用显式转换为 a Predicate
,然后使用该negate
函数进行转换。这是其他一些不太麻烦的方法之一。
与此相反:
Stream<String> s = ...;
int emptyStrings = s.filter(String::isEmpty).count();
这是:
Stream<String> s = ...;
int notEmptyStrings = s.filter(((Predicate<String>) String::isEmpty).negate()).count()
或这个:
Stream<String> s = ...;
int notEmptyStrings = s.filter( it -> !it.isEmpty() ).count();
就个人而言,我更喜欢后一种技术,因为我发现它it -> !it.isEmpty()
比冗长的显式强制转换然后否定更清晰。
也可以创建一个谓词并重用它:
Predicate<String> notEmpty = (String it) -> !it.isEmpty();
Stream<String> s = ...;
int notEmptyStrings = s.filter(notEmpty).count();
或者,如果有一个集合或数组,只需使用一个简单的 for 循环,开销更少,并且 * 可能更快:
int notEmpty = 0;
for(String s : list) if(!s.isEmpty()) notEmpty++;
*如果您想知道什么更快,请使用 JMH http://openjdk.java.net/projects/code-tools/jmh,并避免手动基准代码,除非它避免所有 JVM 优化 - 请参阅Java 8:Streams 的性能与收藏
**我因为建议 for-loop 技术更快而受到抨击。它消除了流创建,消除了使用另一个方法调用(谓词的否定函数),并消除了临时累加器列表/计数器。因此,最后一个构造保存的一些东西可能会使其更快。
我确实认为它更简单更好,即使不是更快。如果工作需要锤子和钉子,不要带电锯和胶水!我知道你们中的一些人对此有异议。
愿望清单:我希望看到 JavaStream
用户对 Java 函数更加熟悉后,它们会有所发展。例如,Stream 中的 'count' 方法可以接受 a Predicate
,因此可以像这样直接完成:
Stream<String> s = ...;
int notEmptyStrings = s.count(it -> !it.isEmpty());
or
List<String> list = ...;
int notEmptyStrings = lists.count(it -> !it.isEmpty());