简介
Java 8 引入的 Stream API 提供了丰富的流式操作方法,可以高效地处理集合数据。这些操作分为中间操作(Intermediate Operations)和终端操作(Terminal Operations)两大类。
注意事项
-
流是一次性的,被终端操作消费后就不能再使用
-
中间操作是惰性的,只有遇到终端操作才会执行
-
流操作不修改原始数据源
-
并行流(
parallelStream()
)可以提高大数据集的处理效率
中间操作(Intermediate Operations)
中间操作会返回一个新的 Stream,可以链式调用,但不会立即执行。
1.筛选与切片
filter(Predicate):过滤元素
Arrays.stream(numbers).filter(n -> n % 2 == 0) // 只保留偶数
distinct():去重
Arrays.stream(duplicates).distinct() // 去除重复元素
limit(long):限制元素数量
Arrays.stream(numbers).limit(3) // 只取前3个元素
skip(long):跳过前N个元素
Arrays.stream(numbers).skip(2) // 跳过前2个元素
2.映射转换
map(Function):元素转换
Arrays.stream(strings).map(String::toUpperCase) // 转为大写
mapToInt/Double/Long:转为基本类型流
Arrays.stream(strings).mapToInt(String::length) // 转为字符串长度流
flatMap(Function):扁平化流
List<List<String>> list = ...;
list.stream().flatMap(List::stream) // 将多个List合并为一个流
3.排序
sorted():自然排序
Arrays.stream(strings).sorted() // 字典序排序
sorted(Comparator):自定义排序
Arrays.stream(people).sorted(Comparator.comparing(Person::getAge)) // 按年龄排序
4.查看元素(调试用)
peek(Consumer):查看流经的元素
Arrays.stream(numbers).peek(n -> System.out.println("处理: " + n))
终端操作(Terminal Operations)
终端操作会触发流的执行,并产生结果或副作用。
1.匹配检查
anyMatch(Predicate):任意元素匹配(检查流中是否至少有一个元素满足给定的条件。)
boolean hasEven = Arrays.stream(numbers).anyMatch(n -> n % 2 == 0);
allMatch(Predicate):所有元素匹配(检查流中是否所有元素都满足给定的条件)
boolean allPositive = Arrays.stream(numbers).allMatch(n -> n > 0);
noneMatch(Predicate):没有元素匹配(检查流中是否没有任何元素满足给定的条件)
boolean noZero = Arrays.stream(numbers).noneMatch(n -> n == 0);
2. 查找元素
findFirst():返回第一个元素
Optional<Integer> first = Arrays.stream(numbers).findFirst();
findAny():返回任意元素(并行流时有用)
Optional<Integer> any = Arrays.stream(numbers).findAny();
3. 聚合计算
count():计数
long count = Arrays.stream(numbers).count();
max(Comparator)/min(Comparator):最大/最小值
Optional<String> longest = Arrays.stream(strings).max(Comparator.comparing(String::length));
sum()/average():求和/平均值(仅限数值流)
int sum = Arrays.stream(new int[]{1,2,3}).sum();
4. 归约操作
reduce(BinaryOperator):归约计算
Optional<Integer> sum = Arrays.stream(numbers).reduce(Integer::sum);
reduce(identity, BinaryOperator):带初始值的归约
int sum = Arrays.stream(numbers).reduce(0, Integer::sum);
5. 收集结果
collect(Collector):转换为集合
List<String> list = Arrays.stream(strings).collect(Collectors.toList());
6. 遍历消费
forEach(Consumer):遍历元素
Arrays.stream(numbers).forEach(System.out::println);
forEachOrdered(Consumer):保证顺序的遍历
Arrays.stream(numbers).parallel().forEachOrdered(System.out::println);