上文我们已经介绍了Stream中间操作,没看过的同学请出门左转 Java 8 Stream(三、Stream中间操作:filter()、distinct()、skip()、limit()、map()、flatMap()、sorted()、peek())。
根据对元素的处理方式,终端操作可分为短路操作(short-circuiting)和非短路操作(non-interfering)。
短路操作: 类似 || 操作符,遇到某些符合条件的元素就可以得到最终结果。短路操作包括anyMatch()、noneMatch()、allMatch()、findAny()、findFirst()。
非短路操作: 类似 && 操作符,必须处理所有元素才能得到最终结果。
void forEach(Consumer<? super T> action);
说明: 接受一个函数式接口Consumer为入参并对所有元素执行该函数。
void forEachOrdered(Consumer<? super T> action);
说明: 接受一个函数式接口Consumer
下面通过串行流和并行流说明两种遍历方式的区别:
Arrays.asList("1", "2", "3").stream().forEach(System.out::println); // 1 2 3
Arrays.asList("1", "2", "3").stream().forEachOrdered(System.out::println); // 1 2 3
Arrays.asList("1", "2", "3").parallelStream().forEach(System.out::println); // 2 3 1
Arrays.asList("1", "2", "3").parallelStream().forEachOrdered(System.out::println); // 1 2 3
boolean anyMatch(Predicate<? super T> predicate);
说明: 接受一个函数式接口Predicate
示例:
System.out.println(Stream.of("1", "2", "3").anyMatch(x -> x.equals("2"))); // true
boolean noneMatch(Predicate<? super T> predicate);
说明: 接受一个函数式接口Predicate
示例:
System.out.println(Stream.of("1", "2", "3").noneMatch(x -> x.equals("4"))); // true
boolean allMatch(Predicate<? super T> predicate);
说明: 接受一个函数式接口Predicate
示例:
System.out.println(Stream.of("1", "2", "3").allMatch(x -> x instanceof String)); // true
这四个操作都返回一个Optional
Optional<T> findAny();
说明: 返回任何一个元素,在串行流中返回第一个元素,在并行流中返回处理最快那个线程的元素。
示例:
System.out.println(Arrays.asList("1", "2", "3").stream().filter(x -> x instanceof String).findAny().orElse(null)); // 1
System.out.println(Arrays.asList("1", "2", "3").parallelStream().filter(x -> x instanceof String).findAny().orElse(null)); // 2
Optional<T> findFirst();
说明: 返回第一个元素,在串行流和并行流中均返回第一个元素。
示例:
System.out.println(Arrays.asList("1", "2", "3").stream().filter(x -> x instanceof String).findFirst().orElse(null)); // 1
System.out.println(Arrays.asList("1", "2", "3").parallelStream().filter(x -> x instanceof String).findFirst().orElse(null)); // 1
Optional<T> max(Comparator<? super T> comparator);
说明: 通过Comparator比较器返回最大元素。
示例:
System.out.println(Arrays.asList("1", "2", "3").stream().max((Comparator.comparing(Function.identity()))).orElse(null)); // 3
Optional<T> min(Comparator<? super T> comparator);
说明: 通过Comparator比较器返回最小元素。
示例:
System.out.println(Arrays.asList("1", "2", "3").stream().min(String::compareTo).orElse(null)); // 1
(三)规约
将流规约成一个值的操作称为规约操作,熟悉MR编程模型的同学应该很好理解。在函数式编程语言的术语中这个过程被称为折叠(fold)。
T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator);
<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);
说明: 该方法存在两个重载方法,每个重载方法接受一个函数式接口BinaryOperator
第一个方法的第一个入参为初始值;
第二个方法因没有初始值故返回一个Optional
第三个方法主要用在并行流中(当在串行流中使用时第三个参数不起作用)。在并行流中,流被Fork Join出多个线程并行执行,每个线程均执行第二个方法。而第三个参数函数式接口BinaryOperator则将每个线程的结果连接起来生成一个新的流,最后使用第一个方法进行规约。
示例:
System.out.println(Stream.iterate(0, x -> x + 1).limit(10).reduce(Integer::sum).orElse(0)); // 45
System.out.println(Stream.iterate(0, x -> x + 1).limit(10).reduce(1000, Integer::sum)); // 1045
System.out.println(Stream.iterate(0, x -> x + 1).limit(10).reduce(1000, Integer::sum, Integer::max)); // 1045
(四)收集
收集操作也可以理解为一种高级的规约操作。
<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner);
<R, A> R collect(Collector<? super T, A, R> collector);
说明: 该方法存在一个重载方法,第二个方法接受一个Collector实例,将流中元素收集成另外一个数据结构。在Collectors静态工厂类中大部分实现调用第一个方法,这几乎满足了我们日常所有操作。
示例:
System.out.println(Stream.iterate(0, x -> x + 1).limit(3).collect(Collectors.toList())); // [0, 1, 2]
Object[] toArray();
<A> A[] toArray(IntFunction<A[]> generator);
说明: 该方法存在一个重载方法,第一个方法的实现也是调用了第二个方法传入一个Object数组。
示例:
System.out.println(Arrays.toString(Stream.iterate(0, x -> x + 1).limit(3).toArray(Integer[]::new))); // [0, 1, 2]
long count();
说明: 返回流中元素个数。
示例:
System.out.println(Stream.iterate(0, x -> x + 1).limit(3).count()); // 3
Java 8 Stream(一、Stream简介及创建方式)
Java 8 Stream(二、Stream操作和无限流)
Java 8 Stream(三、Stream中间操作:filter()、distinct()、skip()、limit()、map()、flatMap()、sorted()、peek())
Java 8 Stream(四、Stream终端操作:forEach()、Match、find()、max、min()、reduce()、collect()、toArray()、count())
Java 8 Stream(五、Optional类和Stream调试)