持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第2天,点击查看活动详情
Hi~ o( ̄▽ ̄)ブ 大家好,这里是杰哥的Java小窝-掘金分站!
1 简介
Steam是Java8中处理集合的关键抽象概念,提供了一种高效且易于使用的数据处理方式,可以执行对指定集合的查找、过滤和映射数据等操作(不会改变源数据集合)。
2 Stream的三个操作步骤及相关函数
2.1 创建Stream
方式1:可通过Collection集合提供的steam()或ParallelStream()来将集合转换为串行流以及并行流
List<String> list = new ArrayList<>();
Stream<String> stringStream = list.stream();
方式2:可通过Arrays中静态方法stream获取数组流
int[] ints = new int[5];
IntStream integerStream = Arrays.stream(ints);
方法3:通过Stream类中的静态方法of()创建
Stream<String> stream = Stream.of("aa", "aa", "aa");
方法4:创建无限流(无穷多项的流)
Stream<Integer> integerStream1 = Stream.iterate(0, (x) -> x + 2);
//or
Stream<Double> doubleStream=Stream.generate(Math::random);
2.2 中间操作
多个中间操作可以连接起来形成一个流水线,除非流水线末端触发终止操作,否则中间操作不会执行。(惰性求值)
| 方法 | 描述 | 备注 |
|---|---|---|
| Stream filter(Predicate<? super T> predicate); | 从流中筛选符合条件的元素 | |
| Stream limit(long maxSize); | 截断流,保留前n个元素(有短路效果,即多个中间操作一起作用时,会截断) | 在流水线操作中有截断效果,即某个流水线有多个中间操作时,对stream遍历至满足limit限制就会停止,可以提高效率。 |
| Stream skip(long n); | 跳过前n个元素 | 若stream中元素不足n个,则返回空stream |
| Stream distinct(); | 去重 | 基于hashCode()和equals()去重,对于自定义对象流要重写才能生效 |
| Stream map(Function<? super T, ? extends R> mapper); | 将流中每个元素都进行转换或提取信息操作,将其映射为一个新的元素 | |
| Stream flatMap(Function<? super T, ? extends Stream<? extends R>> mapper); | 将流中的每个值都转换为另一个流,并把所有流都连接起来返回 | |
| Stream sorted(); | 按照自然顺序排序 | |
| Stream sorted(Comparator<? super T> comparator); | 按照自定义排序规则进行排序 |
2.3 终止操作
| 方法 | 描述 | 备注 |
|---|---|---|
| boolean allMatch(Predicate<? super T> predicate); | 检查是否匹配所有元素 | |
| boolean anyMatch(Predicate<? super T> predicate); | 检查是否至少匹配一个元素 | |
| boolean noneMatch(Predicate<? super T> predicate); | 流里是不是没有元素可以匹配指定规则 | |
| Optional findFirst(); | 返回符合第一个元素 | 使用Optional是因为结果有可能为空 |
| Optional findAny(); | 返回任意值 | |
| Optional max(Comparator<? super T> comparator); | 返回最大值 | |
| Optional min(Comparator<? super T> comparator); | 返回最小值 | |
| long count(); | 返回流中元素总数 | |
| 1.T reduce(T identity, BinaryOperator accumulator); 2.Optional reduce(BinaryOperator accumulator); 3. U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator combiner); | 归约操作: 将流中元素结合起来,得到一个值 | |
| <R, A> R collect(Collector<? super T, A, R> collector); | 收集操作: 将流转换为其他形式(列表、map、set等) | Collectors工具类 提供了很多静态方法可以创建常用的Collector收集器(除此之外还包含很多特殊操作函数,例如 分组groupingBy()、连接字符串joining() 等) |
demo1:归约reduce
List<Integer> list1 = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
//样式1,传入二元运算规则,从identity开始累计结合(避免结果为null,不加起始值需要用Optional接收)
Integer result = list1.stream().reduce(0, Integer::sum);//28
demo2:Collectors 收集List
List<String> nameList=employeeList.stream()
.map(Employee::getName)
.collect(Collectors.toList());
demo3:Collectors List分组
Map<Integer, List<Employee>> map = employeeList.stream()
.collect(Collectors.groupingBy(Employee::getAge));
3 并行流与顺序流
3.1 初识
并行流将一个内容分成多个数据块,并使用不同的线程分别处理每个数据块的流。
demo:顺序流与并行流
// 顺序流
Long sum = LongStream.rangeClosed(0, 1000)//产生0-1000的数字组成LongStream
.reduce(0, Long::sum);
// 并行流
Long sum1 = LongStream.rangeClosed(0, 1000)
.parallel()
.reduce(0, Long::sum);