Java 8 Stream 流详解
Posted 思想累积
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 8 Stream 流详解相关的知识,希望对你有一定的参考价值。
1、stream 简介
Java 8 中有两个重要的改变,一个是 Lambda 表达式,另外一个是 Stream API(java.util.stream.*)
Stream 流的特点:
- stream 流不会改变数据源,一般会产生一个新的集合来存储按照我们特定规则计算后的结果
- stream 会延迟执行,在调用终端操作时中间操作才会执行
1.1 stream 在 java 中的定义:
// 支持顺序和并行聚合操作的元素序列
A sequence of elements supporting sequential and parallel aggregate operations.
// 以下示例演示了使用Stream和IntStream的聚合操作:
The following example illustrates an aggregate operation using Stream and IntStream:
// 示例:
int sum = widgets.stream()
.filter(w -> w.getColor() == RED)
.mapToInt(w -> w.getWeight())
.sum();
Stream 是 Java8 中处理集合的关键抽象概念,它可以指定希望对集合进行的操作,可以执行复杂的查找、过滤和映射数据等操作
1.2 Stream 流接口继承关系
最上面的 AutoCloseable
这个接口只有一个方法
void close() throws Exception;
这个方法关闭调用对象,释放可能占用的所有资源。在带资源的try语句的末尾,会自动调用该方法,不用显式调用close()方法
BaseStream 接口:
BaseStream
这个接口是 Stream 流的基类,这个类定义了 Stream 流的主要行为
public interface BaseStream<T, S extends BaseStream<T, S>> extends AutoCloseable
//获得流的迭代器(终端操作)
Iterator<T> iterator();
// 获取流的并行迭代器(终端操作)
Spliterator<T> spliterator();
// 并行流返回true,顺序流返回false
boolean isParallel();
// 返回一个顺序流(中间操作)
S sequential();
// 返回一个并行流(中间操作)
S parallel();
// 返回一个无序流(中间操作)
S unordered();
// 关闭流时调用,返回一个新流
S onClose(Runnable closeHandler);
// 父类 AutoCloseable 关闭流的方法
@Override
void close();
1.3 中间操作和终端操作
Stream 流上的操作可以分为 中间操作(Intermediate)和终端操作(Terminal)
中间操作
- 中间操作会产生一个新的 Stream 流,可以多个中间操作叠加
- 中间操作不是立即发生的,而是延迟发生的,中间操作创建的新流执行完终端操作后才会发生
终端操作
- 终端操作返回我们最终需要的数据,只能有一个终止操作
2、Stream 流使用
2.1 Stream 流创建
-
通过
Collection
接口的stream()
或者parallelStream()
方法创建List<String> list = Arrays.asList("1", "2", "3"); // 创建普通流,主线程按顺序对流进行操作 Stream<String> stream1 = list.stream(); // 创建并行流,多线程并行对流进行操作 Stream<String> stream2 = list.parallelStream(); // 使用 parallel() 将顺序流转换为并行流 Stream<String> stream8 = stream1.parallel();
-
使用
Stream
的静态方法
Stream<String> stream3 = Stream.empty(); Stream<String> stream4 = Stream.of("1", "2", "3"); // 将两个流连接起来 Stream<String> stream5 = Stream.concat(stream1, stream2); ... ... Stream.generate(); Stream.iterate();
-
使用
Arrays
的stream()
方法int[] arr = 1, 2, 3; IntStream stream = Arrays.stream(arr);
2.2 Stream 流中间操作(Intermediate)
-
filter(Predicate):
筛选
,结果为 false 的元素会过滤掉List<String> list = Arrays.asList("1", "2", "3", "4", "5"); // 筛选等于 "3" 的第一个元素 Optional<String> first = list.stream().filter(x -> x == "3").findFirst(); System.out.println(first.get()); // 输出结果:3
-
map:
映射
-
map(fun):转换元素的值,一个流的元素按函数处理后映射为新的元素
List<String> list = Arrays.asList("he", "ha", "hia", "hua"); // 所有元素大写 list.stream().map(x -> x.toUpperCase()).forEach(System.out::println); // 输出结果:HE HA HIA HUA
-
flatMap(fun):流中的每个值都换成另外一个流,再将所有的流连接成一个
List<String> list = Arrays.asList("h-e", "h-a", "h-i-a", "h-u-a"); List<String> collect = list.stream().flatMap(x -> Arrays.stream(x.split("-"))).collect(Collectors.toList()); System.out.println(collect); // 输出结果:[h, e, h, a, h, i, a, h, u, a]
-
-
limit(n):
截取
,保留 n 个元素List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6); // 保留 3 个元素 list.stream().limit(3).forEach(System.out::println); // 输出结果:1 2 3
-
skip(n):
跳过
,跳过 n 个元素List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3"); // 跳过 3 个元素筛选等于 "3" 的第一个元素 Optional<String> first = list.stream().skip(3).filter(x -> x == "3").findFirst(); System.out.println(first); // 输出结果:3
-
distinct():
去重
,去除重复元素List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3"); // 去重遍历 list.stream().distinct().forEach(System.out::println);
-
sorted:
排序
自然排序List<Integer> list = Arrays.asList(5, 2, 3, 4, 5, 2, 3, 6); // 去重并排序 List<Integer> collect = list.stream().distinct().sorted().collect(Collectors.toList()); System.out.println(collect);
2.3 Stream 流终止操作(Terminal)
-
foreach:遍历
List<String> list = Arrays.asList("he", "ha", "hia", "hua"); // 遍历输出 list.stream().forEach(x -> System.out.println(x); ); // 结果:he ha hia hua
-
find
List<String> list = Arrays.asList("1", "2", "3", "4", "5"); // 筛选等于 "3" 的第一个元素 Optional<String> first = list.stream().filter(x -> x == "3").findFirst(); System.out.println(first.get()); // 输出结果:3
-
count()
List<String> list = Arrays.asList("1", "2", "3", "4", "5", "3"); // 等于 "3" 的元素的数量 long count = list.stream().filter(x -> x == "3").count(); System.out.println(count); // 输出结果:2
-
max(Comparator)
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6); // 集合中最大的元素 Optional<Integer> max = list.stream().max(Integer::compareTo); System.out.println(max.get()); // 结果为:6
-
min(Comparator)
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 2, 3, 6); // 集合中最小的元素 Optional<Integer> max = list.stream().min(Integer::compareTo); System.out.println(max.get()); // 结果为:1
-
reduce:缩减,可以把一个 stream 流缩减成一个值,实现求和、求最值等操作
-
求和
// 对集合中的元素求和 List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 第一种求和方式 Integer sum = list.stream().reduce((x, y) -> x + y).get(); // 第二种求和方式 Integer sum2 = list.stream().reduce(Integer::sum).get(); // 第三种求和方式(集合中的元素求和再加 1) Integer sum3 = list.stream().reduce(3, Integer::sum);
-
求最值
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 求最大值 1 Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y); // 求最大值 2 Integer sum2 = list.stream().reduce(Integer::max).get();
-
-
collect:收集操作,把 stream 流收集起来,成为一个新的值或者集合
-
toList
、toSet
、toMap
List<String> list = Arrays.asList("he", "ha", "hia", "hua", null); // toList List<String> collect = list.stream().filter(Objects::nonNull).collect(Collectors.toList()); System.out.println(collect); //[he, ha, hia, hua] // toSet Set<String> set = list.stream().filter(Objects::nonNull).collect(Collectors.toSet()); System.out.println(set); // [hia, hua, ha, he] // toMap Map<String, String> map = list.stream().filter(Objects::nonNull).collect(Collectors.toMap(x -> x, x -> x)); System.out.println(map); // hia=hia, hua=hua, ha=ha, he=he
-
平均值
averagingDouble
、averagingLong
、averagingInt
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 求平均值 Double average = list.stream().collect(Collectors.averagingDouble(Integer::intValue)); System.out.println(average);
-
计数
count
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 求总数 Long count = list.stream().collect(Collectors.counting()); System.out.println(count);
-
最值
maxBy
、minBy
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 求最高值 Integer max = list.stream().collect(Collectors.maxBy(Integer::compare)).get(); System.out.println(max);
-
求和
summingInt
、summingLong
、summingDubbo
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 求和 Integer sum = list.stream().collect(Collectors.summingInt(Integer::intValue)); System.out.println(sum);
-
统计所有
summarizingInt
、summarizingLong
、summarizingDouble
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5); // 统计所有信息 DoubleSummaryStatistics collect = list.stream().coll
以上是关于Java 8 Stream 流详解的主要内容,如果未能解决你的问题,请参考以下文章
-