stream流的介绍与实践

 一、stream流介绍

                在Java8之后,Java新增了java.util.stream 包,它允许你以声明式的方式处理集合数据,使得代码更加的简介、更易读,同时提供了强大的处理能力。

        stream是一种数据处理现象,它不是数据结构,而是从数据源(集合、数组)生成的元素序列,并支持各种聚合操作(过滤、映射、排序等)。stream的特点是:

        (1)不存储数据:stream只是对数据源进行视图话操作,不改变原始数据。

        (2)函数式编程:所有操作都是以函数式风格进行,支持lambda表达式。

        (3)延迟执行:中间操作(如filter、map)不会立即执行、只有终止操作(如collect、forEach)才会触发计算。

        (4)可消费性:stream只能被消费一次,消费后需要重新创建。

二、stream流的实践

1、stream的基本操作流程

        (1)创建stream:从集合、数组等数据源获取stream。

        (2)中间操作:对stream中的元素及进行转换或过滤,返回一个新的stream。

        (3)终止操作:触发实际计算,产生结果(如集合、数值或副作用)。

示例代码:

List names = Arrays.asList("Alice", "Bob", "Charlie", "David");

// 创建 Stream → 中间操作(过滤长度>4)→ 中间操作(转换为大写)→ 终止操作(收集结果)
List result = names.stream()
    .filter(name -> name.length() > 4)
    .map(String::toUpperCase)
    .collect(Collectors.toList());

// 结果:[ALICE, CHARLIE, DAVID]

2、中间操作

        中间操作返回一个新的stream,对于元素进行转换或过滤。常见的中间操作:

操作 描述 实例
filter 过滤满足条件的元素 stream.filter(num -> num > 10)
map 将元素转换为另一种类型 stream.map(String::length)
flatMap 将嵌套的 Stream 展开为单个 Stream stream.flatMap(list -> list.stream())
distinct 去重(基于 equals 和 hashCode stream.distinct()
sorted 排序(自然顺序或指定比较器) stream.sorted((a, b) -> a.compareTo(b))
limit 截断 Stream,返回前 n 个元素 stream.limit(5)
skip 跳过前 n 个元素 stream.skip(3)
peek 调试工具,对每个元素执行副作用(如打印) stream.peek(System.out::println)

3、终止操作

        终止操作触发stream的执行并产生结果。常见的终止操作:

操作 描述 示例
forEach 遍历元素 stream.forEach(System.out::println)
collect 将元素收集到集合或其他数据结构中 stream.collect(Collectors.toList())
toArray 将元素转换为数组 stream.toArray(String[]::new)
reduce 聚合元素为单个值(如求和、求最大值) stream.reduce(0, Integer::sum)
count 统计元素数量 stream.count()
anyMatch 判断是否至少有一个元素满足条件 stream.anyMatch(s -> s.contains("a"))
allMatch 判断所有元素是否都满足条件 stream.allMatch(s -> s.length() > 0)
noneMatch 判断所有元素是否都不满足条件 stream.noneMatch(s -> s.isEmpty())
findFirst 返回第一个元素(可能为空,返回 Optional stream.findFirst()
findAny 返回任意一个元素(并行流中可能随机返回) stream.findAny()

4、收集器(Collectors)

        Collectors工具类提供了强大的聚合功能,用于将stream元素手机到各种数据结构中:

收集器 描述 示例
toList() 收集元素到 List 中 stream.collect(Collectors.toList())
toSet() 收集元素到 Set 中(自动去重) stream.collect(Collectors.toSet())
toMap() 收集元素到 Map 中(需指定键和值的映射) stream.collect(Collectors.toMap(Person::getId, Person::getName))
groupingBy 按条件分组,返回 Map> stream.collect(Collectors.groupingBy(Person::getDepartment))
partitioningBy 按布尔条件分区,返回 Map> stream.collect(Collectors.partitioningBy(p -> p.getAge() > 18))
joining 连接字符串元素 stream.collect(Collectors.joining(", "))
summingInt/Double/Long 对数值类型求和 stream.collect(Collectors.summingInt(Person::getAge))
averagingInt/Double/Long 计算平均值 stream.collect(Collectors.averagingDouble(Person::getScore))
maxBy/minBy 求最大值 / 最小值(需传入比较器) stream.collect(Collectors.maxBy(Comparator.comparing(Person::getAge)))

5、并行流

        stream支持并行处理,通过parallel()方法将顺序流转换为并行流,利用多核CPU提升性能:

// 顺序流:单线程处理
List numbers = Arrays.asList(1, 2, 3, 4, 5);
int sumSequential = numbers.stream()
    .mapToInt(Integer::intValue)
    .sum();

// 并行流:多线程处理(适用于大数据集)
int sumParallel = numbers.parallelStream()
    .mapToInt(Integer::intValue)
    .sum();

/**
*
*注意事项:
*1、并行流的线程安全问题(避免共享可变状态)。
*2、并非所有场景都适合并行(如小数据集或 IO 密集型操作)。
*3、使用 sequential() 方法可将并行流转回顺序流。
*
**/

结语:

        掌握 Stream 流是现代 Java 开发的必备技能,它让代码更简洁、更具表现力,同时提升了开发效率和程序性能。

你可能感兴趣的:(Java,java)