Java 8谓词选择最大

时间:2016-12-08 04:40:06

标签: java java-8 java-stream predicate

这是一个由两部分组成的问题。我只是在学习Java 8中的谓词,我需要知道是否有一个谓词我可以传递给filter()方法来选择整数列表中的max,如下所示:

List<Integer> numbers = ...
Integer max = numbers.stream()
                     .filter(n -> ???)
                     .getFirst()
                     .get();

更大的问题是:可以用数学方式对谓词进行链接,这样就不需要链接filter()reduce()方法,这样在一个谓词中完成的工作就可以反映或传递给以下一个,所以不是写作:

list.stream()
    .filter(/* predicate1 */
            item -> {
                        // do some work and save in some local variable "var"
                    })
    .filter(/* predicate2 */ var -> ...)
    .reduce(predicate3)
    .getFirst()
    .get();

我可以写:

list.stream()
    .filter(predicate1 "andThen" predicate2 "andThen" reduce by predicate3)
    .getFirst()
    .get();

我推测可能有一种方法可以使用andThen()功能或编写自定义谓词。谁能帮助我更好地理解这一点?

1 个答案:

答案 0 :(得分:3)

不,您无法使用filter(Predicate)选择Stream的最大值。

您还有其他多种选择:

stream.max(Comparator.naturalOrder());
stream.sorted(Comparator.reverseOrder()).findFirst();
stream.mapToInt(i -> i).max();
stream.reduce(Integer::max);

是的,Predicate可以由and(Predicate)链接。实现基本上如下:

Predicate<T> and(Predicate<? super T> other) {
    return t -> test(t) && other.test(t);
}

您也可以自己编写:

static <T> Predicate<T> and(Predicate<? super T>... ps) {
    return t -> Stream.of(ps).allMatch(p -> p.test(t));
}

用法:

stream.filter(and(i -> i > 11, i -> i < 50))

您可以应用多个过滤器,因此您通常会将调用链接起来:

stream.filter(i -> i > 11).filter(i -> i < 50)

您了解reduce(BinaryOperator)的作用吗?你不能在那里放Predicate。 我已经在上面使用它作为获得最大值的选项。