Stream 流终端操作

短路操作

distinct

  • 接口定义:Stream<T> distinct()

  • 方法描述:在 distinct 接口定义中,返回一个去除重复元素的流。该方法是根据hashCodeequals方法来判断元素是否相等。因此,我们的类必须实现hashCodeequals方法。如果distinct方法正在处理有序流,那么对于重复元素,将保留第一个元素。并且这种方式选择不同元素是稳定的。在无序流中,不同元素的选择是任意的。在有序流的并行流中,保持 distinct()操作的稳定性是非常昂贵的,它需要大量的缓冲区和额外的工作。如果我们不关心保持流的有序性,那么我们可以使用unordered()方法来取消有序性,这样可以提高性能。

List<String> list = Arrays.asList("a", "b", "c", "a", "b", "c");
list.stream().distinct().forEach(System.out::println);

sorted

对元素进行排序,通过 Comparator 来指定排序规则。

  • 接口定义:

    • Stream<T> sorted()

    • Stream<T> sorted(Comparator<? super T> comparator)

  • 方法描述:

    • 当使用Stream<T> sorted()时,返回一个按自然顺序排序的流。

    • 当使用Stream<T> sorted(Comparator<? super T> comparator)时,返回一个按指定规则排序的流。

List<String> list = Arrays.asList("c", "a", "b");
list.stream().sorted().forEach(System.out::println);

skip

跳过指定数量的元素,返回一个扔掉了前 n 个元素的流。如果流中元素不足 n 个,则返回一个空流。与 limit(n) 互补。

  • 接口定义:Stream<T> skip(long n)

  • 方法描述:在 skip 接口定义中,返回一个扔掉了前 n 个元素的流。

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
list.stream().skip(2).forEach(System.out::println);

limit

截断流,使其元素不超过给定数量。

  • 接口定义:Stream<T> limit(long maxSize)

  • 方法描述:在 limit 接口定义中,返回一个截断流,使其元素不超过给定数量。

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
list.stream().limit(2).forEach(System.out::println);

非短路操作

max

返回流中所有元素的最大值。

  • 接口定义:Optional<T> max(Comparator<? super T> comparator)

  • 方法描述:在max接口定义中,接收一个Comparator函数式接口作为参数,用于比较元素的大小。

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> max = list.stream().max(Integer::compareTo);
System.out.println(max.get());

min

返回流中所有元素的最小值。

  • 接口定义:Optional<T> min(Comparator<? super T> comparator)

  • 方法描述:在min接口定义中,接收一个 Comparator 函数式接口作为参数,用于比较元素的大小。

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> min = list.stream().min(Integer::compareTo);
System.out.println(min.get());

count

返回流中元素的个数。

  • 接口定义:long count()

  • 方法描述:在 count 接口定义中,返回流中元素的个数。

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
long count = list.stream().count();
System.out.println(count);

reduce

将流中元素反复结合起来,得到一个值。

  • 接口定义:

    • 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)

  • 方法描述:

    • 当使用Optional<T> reduce(BinaryOperator<T> accumulator)时,通过累加器 accumulator 对流中所有元素进行累积操作,返回一个 T 类型的 Optional 对象。

    • 当使用T reduce(T identity, BinaryOperator<T> accumulator)时,给定一个初始值 identity,通过累加器 accumulator 对流中所有元素进行累积操作,返回一个 Stream 中元素类型相同的对象。

    • 当使用<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner)时,给定一个初始值 identity,通过累加器 accumulator 对流中所有元素进行累积操作,得到一个 identity 类型的结果,第三个参数用于使用并行流时,将多个结果合并。

// 不使用Optional,需要给定初始值
// 求和
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.stream().reduce(0, Integer::sum);

// 求最小值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Integer min = list.stream().reduce(Integer.MAX_VALUE, Integer::min);
System.out.println(min);

// 使用Optional,不需要给定初始值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> sum = list.stream().reduce(Integer::sum);

// 使用并行流
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = list.parallelStream().reduce(0, Integer::sum, Integer::sum);

forEach

遍历元素,对每个元素执行操作。在并发流中,forEach 无法保证元素的顺序。

  • 接口定义:void forEach(Consumer<? super T> action)

  • 方法描述:在 forEach 接口定义中,接收一个 Consumer 函数式接口作为参数,用于对流中的每个元素执行操作。

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
list.stream().forEach(System.out::println);

// 并发流
List<String> list = Arrays.asList("a", "b", "c", "d", "e");
list.parallelStream().forEach(System.out::println);

forEachOrdered

遍历元素,对每个元素执行操作。在并发流中,forEachOrdered 保证元素的顺序。

  • 接口定义:void forEachOrdered(Consumer<? super T> action)

  • 方法描述:在 forEachOrdered 接口定义中,接收一个 Consumer 函数式接口作为参数,用于对流中的每个元素执行操作。

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
list.parallelStream().forEachOrdered(System.out::println);

toArray

将流转换为数组。

  • 接口定义:

    • Object[] toArray()

    • T[] toArray(IntFunction<A[]> generator)

  • 方法描述:在 toArray 接口定义中,返回一个数组,可以通过 toArray() 方法将流转换为数组。

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
String[] arr = list.stream().toArray(String[]::new);

collect

将流转换为其他形式。接收一个 Collector 接口的实现,用于给流中元素做汇总的方法。

  • 接口定义:

    • <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)

  • 方法描述:

    • 当使用<R, A> R collect(Collector<? super T, A, R> collector)时,接收一个 Collector 接口的实现,用于给流中元素做汇总的方法。

    • 当使用<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R> combiner)时,需要给定一个初始值,通过累加器 accumulator 对流中所有元素进行累积操作,第三个参数用于使用并行流时,将多个结果合并。

List<String> list = Arrays.asList("a", "b", "c", "d", "e");
Stream<String> stream = list.stream();
// 设置索引 No1: a No2: b No3: c No4: d No5: e
List<String> collect = stream.collect(ArrayList::new, (list1, item) -> list1.add("No" + (list1.size() + 1) + ": " + item), ArrayList::addAll);
System.out.println(collect);

最后更新于

这有帮助吗?