阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

其他操作

34次阅读
没有评论

共计 2761 个字符,预计需要花费 7 分钟才能阅读完成。

我们把 Stream 提供的操作分为两类:转换操作和聚合操作。除了前面介绍的常用操作外,Stream还提供了一系列非常有用的方法。

排序

Stream 的元素进行排序十分简单,只需调用 sorted() 方法:

import java.util.*;
import java.util.stream.*;

public class Main {public static void main(String[] args) {List<String> list = List.of("Orange", "apple", "Banana")
            .stream()
            .sorted()
            .collect(Collectors.toList());
        System.out.println(list);
    }
}

此方法要求 Stream 的每个元素必须实现 Comparable 接口。如果要自定义排序,传入指定的 Comparator 即可:

List<String> list = List.of("Orange", "apple", "Banana")
    .stream()
    .sorted(String::compareToIgnoreCase)
    .collect(Collectors.toList());

注意 sorted() 只是一个转换操作,它会返回一个新的Stream

去重

对一个 Stream 的元素进行去重,没必要先转换为Set,可以直接用distinct()

List.of("A", "B", "A", "C", "B", "D")
    .stream()
    .distinct()
    .collect(Collectors.toList()); // [A, B, C, D]

截取

截取操作常用于把一个无限的 Stream 转换成有限的 Streamskip() 用于跳过当前 Stream 的前 N 个元素,limit()用于截取当前 Stream 最多前 N 个元素:

List.of("A", "B", "C", "D", "E", "F")
    .stream()
    .skip(2) // 跳过 A, B
    .limit(3) // 截取 C, D, E
    .collect(Collectors.toList()); // [C, D, E]

截取操作也是一个转换操作,将返回新的Stream

合并

将两个 Stream 合并为一个 Stream 可以使用 Stream 的静态方法concat()

Stream<String> s1 = List.of("A", "B", "C").stream();
Stream<String> s2 = List.of("D", "E").stream();
// 合并:
Stream<String> s = Stream.concat(s1, s2);
System.out.println(s.collect(Collectors.toList())); // [A, B, C, D, E]

flatMap

如果 Stream 的元素是集合:

Stream<List<Integer>> s = Stream.of(Arrays.asList(1, 2, 3),
        Arrays.asList(4, 5, 6),
        Arrays.asList(7, 8, 9));

而我们希望把上述 Stream 转换为Stream<Integer>,就可以使用flatMap()

Stream<Integer> i = s.flatMap(list -> list.stream());

因此,所谓 flatMap(),是指把Stream 的每个元素(这里是List)映射为Stream,然后合并成一个新的Stream

┌─────────────┬─────────────┬─────────────┐
│┌───┬───┬───┐│┌───┬───┬───┐│┌───┬───┬───┐│
││ 1 │ 2 │ 3 │││ 4 │ 5 │ 6 │││ 7 │ 8 │ 9 ││
│└───┴───┴───┘│└───┴───┴───┘│└───┴───┴───┘│
└─────────────┴─────────────┴─────────────┘
                     │
                     │flatMap(List -> Stream)
                     │
                     │
                     ▼
   ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐
   │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │
   └───┴───┴───┴───┴───┴───┴───┴───┴───┘

并行

通常情况下,对 Stream 的元素进行处理是单线程的,即一个一个元素进行处理。但是很多时候,我们希望可以并行处理 Stream 的元素,因为在元素数量非常大的情况,并行处理可以大大加快处理速度。

把一个普通 Stream 转换为可以并行处理的 Stream 非常简单,只需要用 parallel() 进行转换:

Stream<String> s = ...
String[] result = s.parallel() // 变成一个可以并行处理的 Stream
                   .sorted() // 可以进行并行排序
                   .toArray(String[]::new);

经过 parallel() 转换后的 Stream 只要可能,就会对后续操作进行并行处理。我们不需要编写任何多线程代码就可以享受到并行处理带来的执行效率的提升。

其他聚合方法

除了 reduce()collect()外,Stream还有一些常用的聚合方法:

  • count():用于返回元素个数;
  • max(Comparator<? super T> cp):找出最大元素;
  • min(Comparator<? super T> cp):找出最小元素。

针对 IntStreamLongStreamDoubleStream,还额外提供了以下聚合方法:

  • sum():对所有元素求和;
  • average():对所有元素求平均数。

还有一些方法,用来测试 Stream 的元素是否满足以下条件:

  • boolean allMatch(Predicate<? super T>):测试是否所有元素均满足测试条件;
  • boolean anyMatch(Predicate<? super T>):测试是否至少有一个元素满足测试条件。

最后一个常用的方法是 forEach(),它可以循环处理Stream 的每个元素,我们经常传入 System.out::println 来打印 Stream 的元素:

Stream<String> s = ...
s.forEach(str -> {System.out.println("Hello," + str);
});

小结

Stream提供的常用操作有:

转换操作:map()filter()sorted()distinct()

合并操作:concat()flatMap()

并行处理:parallel()

聚合操作:reduce()collect()count()max()min()sum()average()

其他操作:allMatch(), anyMatch(), forEach()

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2024-08-05发表,共计2761字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中