本文为个人总结,如有错误请评论区指出
文章目录
什么是Stream流
Stream 是Java 8 引入的对集合数据进行"流水线式"处理的工具。
Stream流的四个特性
无存储性
Stream不保存数据,数据始终存储在原始数据源(集合、数组)中,Stream只负责处理
不变性
Stream操作不会修改原始数据源 ,所有的中间操作都会返回新的Stream,保证原数据不变
惰性执行
中间操作 (如:filter、map、sorted)仅记录处理逻辑 ,不立即执行;只有调用终止操作 (如collect、forEach、count)时,才会触发整个流的执行
- 中间操作:调用后不会立即执行,只是记录操作逻辑,返回新的Stream
- 终止操作:只有调用终止操作时,所有中间才会一次性执行,执行完后Stream就会失效
一次性
Stream流是单向的、不可复用的 ,一旦执行了终止操作 ,这个Stream就会被消费掉,无法再次使用;如果需要重新操作数据,必须从数据源重新创建Stream
Stream常用操作
创建操作
- 从集合创建(
stream () /parallelStream ())
- stream():从 Collection 集合(List/Set/Map.values () 等)创建串行流,单线程按顺序处理元素;
- parallelStream():创建并行流,多线程分发处理元素,顺序不可控,但大数据量下效率更高。
java
//从集合创建
List<String> list = Arrays.asList("wz","xg");
list.stream().forEach(System.out::print); // 输出: wzxg
list.parallelStream().forEach(System.out::print); // 输出:xgwz(并行流顺序可能乱)
- 从数组创建(
Arrays.stream ())
- 专门处理数组的流创建方法,会拆分数组元素生成流,而非将数组作为单个元素
- 处理基本类型数组时,优先使用 Arrays.stream(),避免 Stream.of() 导致的 Stream<int[]> 类型问题;
- 数组为 null 时会抛出
NullPointerException,需提前判空。
java
//从数组创建
String[] arr = {"wz","xg"};
Arrays.stream(arr).forEach(System.out::print); // 输出: wzxg
- 直接生成(
Stream.of ())
- 允许传入 null 元素,但易引发后续空指针异常
- 处理基本类型数组时(如 int[] arr = {1,2}),Stream.of(arr) 会生成 Stream<int[]>(数组作为单个元素),而非拆分元素。
java
//直接生成
Stream.of("wzxg",666).forEach(System.out::print); // 输出: wzxg666
- 生成无限流(
Stream.generate () / Stream.iterate ())
方法定义:
java
// 生成无限流:基于 Supplier 生成无规律元素
static <T> Stream<T> generate(Supplier<T> s)
// 生成无限流:基于初始值+迭代器生成有规律元素
static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
// Java 9+ 重载:支持终止条件
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
generate():通过Supplier函数无规律生成无限元素 (如随机数),需配合limit()截断;iterate():基于初始值(seed) 和迭代函数(UnaryOperator) 生成有规律的无限元素 (如自增序列),Java 9+ 可指定终止条件。
java
//生成无限流(需limit截断)
Stream.generate(Math::random).limit(2).forEach(n->System.out.printf("%.1f ",n)); // 输出: 0.1 0.2(随机值)
Stream.iterate(0, n->n+1).limit(2).forEach(System.out::print); // 输出:01
中间操作
- filter:过滤元素
方法定义:
java
Stream<T> filter(Predicate<? super T> predicate)
接收一个判断条件(Predicate 函数式接口),保留流中满足条件的元素,过滤掉不满足条件的元素,返回新的 Stream。
java
Stream.of(1,2,3).filter(n->n%2==0).forEach(System.out::print); // 输出: 2
- map:转换元素(一对一)
方法定义:
java
<R> Stream<R> map(Function<? super T, ? extends R> mapper)
- T:原Stream中的元素类型
- R:转换后新Stream中元素的类型
- mapper:一个函数式接口,接收一个T类型元素,返回一个R类型结果,这个函数就是定义的转换规则
java
Stream.of("a","b").map(String::toUpperCase).forEach(System.out::print); // 输出: AB
- flatMap:扁平化流(一对多)
方法定义:
java
<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)
接收一个 "生成流" 的函数,将流中每个元素转换为一个新的子流,再将所有子流 "扁平化" 合并为一个整体流
java
Stream.of(new String[]{"a","b"}, new String[]{"c"})
.flatMap(Arrays::stream)// 每个数组转成子流,再合并
.forEach(System.out::print); // 输出: abc
- distinct:去重
java
Stream.of("a","a","b")
.distinct()//去重
.forEach(System.out::print); // 输出: ab
- sorted:排序
方法定义:
java
// 自然排序
Stream<T> sorted()
// 自定义排序(指定 Comparator)
Stream<T> sorted(Comparator<? super T> comparator)
- 无参
sorted():按元素的自然顺序排序(如数字升序、字符串字典序) - 有参
sorted(Comparator):按自定义规则排序,无需元素实现 Comparable。
java
Stream.of(3,1,2)
.sorted()
.forEach(System.out::print); // 输出: 123
- limit:保留前 N 个元素
java
Stream.of(1,2,3)
.limit(2)
.forEach(System.out::print); // 输出: 12
- skip:跳过前 N 个元素
java
Stream.of(1,2,3)
.skip(1)
.forEach(System.out::print); // 输出: 23
- peek:调试消费元素
java
Stream.of(1,2)
.peek(System.out::print)
.count(); // 输出: 12
终止操作
- forEach:遍历元素
java
Stream.of("a","b").forEach(System.out::print); // 输出: ab
- collect:收集结果(转换集合 / 数组)
方法定义:
java
<R, A> R collect(Collector<? super T, A, R> collector)
- 接收
Collector,将流中元素聚合为指定类型的结果(如 List、Set、Map) Collectors提供了丰富的收集器(toList()/toSet()/groupingBy() 等);- 自定义收集器需实现
Collector接口,适合复杂聚合场景。
java
List<String> list = Stream.of("a").collect(Collectors.toList()); // list = ["a"]
- toArray:转数组
java
String[] arr = Stream.of("a").toArray(String[]::new); // arr = ["a"]
- count:统计元素个数
返回流中元素的总个数,返回值为 long 类型(避免 int 溢出)
java
long num = Stream.of(1,2,3).count(); // num = 3
- max:找最大值
java
int max = Stream.of(1,2).max(Integer::compare).get(); // max = 2
- min:找最小值
java
int min = Stream.of(1,2).min(Integer::compare).get(); // min = 1
- findFirst:找第一个元素
java
int first = Stream.of(1,2).findFirst().get(); // first = 1
- findAny:找任意元素
java
int any = Stream.of(1,2,3).findAny().get(); // any = 1(串行流通常返回第一个)
- anyMatch:是否存在符合条件元素
java
boolean b1 = Stream.of(1,2).anyMatch(n-> n>1); // b1 = true 2大于1
- allMatch:所有元素是否符合条件
java
boolean b2 = Stream.of(2,4).allMatch(n->n%2==0); // b2 = true 2,4都可以被2整除
- noneMatch:是否无符合条件元素
java
boolean b3 = Stream.of(1,3).noneMatch(n->n%2==0); // b3 = true 1,3都不能被2整除
- reduce:归约(聚合为单个值)
java
int sum = Stream.of(1,2).reduce(0, Integer::sum); // sum = 3 1+2=3