Stream流-从进阶到起飞

🌈个人主页 :一条泥憨鱼 (欢迎各位大佬莅临)

🎬精选专栏:数据结构与算法JavaSE,苍穹外卖日记

前言:

为了让集合操作变得:

  • 更简洁

  • 更优雅

  • 更像"操作数据流水线"

在 Java 8 之后,Java 增加了一个非常重要的特性:

Stream 流

很多同学第一次看到 Stream 时都会觉得:

java 复制代码
list.stream()

好抽象。其实本质上:

Stream 就是一种"处理数据"的方式。

类似:

java 复制代码
筛选数据
排序数据
统计数据
加工数据

一、为什么要学习 Stream?

假设:我们要找出集合中所有年龄大于 18 的人。


传统写法

java 复制代码
ArrayList<Integer> list = new ArrayList<>();

list.add(10);
list.add(20);
list.add(30);

ArrayList<Integer> result = new ArrayList<>();

for(Integer age : list){

    if(age > 18){
        result.add(age);
    }
}

System.out.println(result);

虽然能实现。但是:

  • 代码繁琐

  • 逻辑不够清晰

  • 需要手动循环


Stream 写法

java 复制代码
list.stream()
    .filter(age -> age > 18)
    .forEach(System.out::println);

是不是一下子简洁很多?

哈哈,这就是 Stream 的魅力。


二、什么是 Stream?

Stream 翻译:

我们可以理解为:数据在"流水线"中进行加工处理。

如:

java 复制代码
原始数据
   ↓
过滤
   ↓
排序
   ↓
去重
   ↓
输出结果

三、Stream 的特点

特点 说明
不存储数据 只是处理数据
不改变原集合 原集合不会变
支持链式操作 写法简洁
函数式编程 Lambda 表达式

四、创建 Stream 流


1. List 创建 Stream

java 复制代码
List<String> list = new ArrayList<>();

Stream<String> stream = list.stream();

2. Set 创建 Stream

java 复制代码
Set<String> set = new HashSet<>();

Stream<String> stream = set.stream();

3. Map 创建 Stream

**Map 不能直接 stream,**需要:

java 复制代码
map.keySet().stream()

map.values().stream()

map.entrySet().stream()

示例

java 复制代码
Map<Integer,String> map = new HashMap<>();

map.put(1,"Java");
map.put(2,"Python");

map.entrySet().stream()
        .forEach(System.out::println);

4. 数组创建 Stream

java 复制代码
Arrays.stream(arr)

示例

java 复制代码
int[] arr = {1,2,3};

Arrays.stream(arr)
        .forEach(System.out::println);

五、Stream 常用方法

Stream 操作分两类:

类型 说明
中间操作 返回新的 Stream
终结操作 结束 Stream

六、中间操作


1. filter() 过滤

作用:

筛选数据


示例:过滤偶数

java 复制代码
import java.util.Arrays;

public class Demo {

    public static void main(String[] args) {

        Arrays.asList(1,2,3,4,5,6)
                .stream()
                .filter(n -> n % 2 == 0)
                .forEach(System.out::println);
    }
}

输出:

java 复制代码
2
4
6

2. map() 加工数据

作用:

转换数据


示例:数字平方

java 复制代码
import java.util.Arrays;

public class Demo {

    public static void main(String[] args) {

        Arrays.asList(1,2,3)
                .stream()
                .map(n -> n * n)
                .forEach(System.out::println);
    }
}

输出:

复制代码
1
4
9

3. sorted() 排序


示例

java 复制代码
Arrays.asList(5,1,3,2)
        .stream()
        .sorted()
        .forEach(System.out::println);

输出:

复制代码
1
2
3
5

降序排序

复制代码
.sorted((a,b) -> b - a)

4. distinct() 去重


示例

java 复制代码
Arrays.asList(1,1,2,2,3,3)
        .stream()
        .distinct()
        .forEach(System.out::println);

输出:

复制代码
1
2
3

5. limit() 获取前几个


示例

java 复制代码
Arrays.asList(1,2,3,4,5)
        .stream()
        .limit(3)
        .forEach(System.out::println);

输出:

复制代码
1
2
3

6. skip() 跳过元素


示例

java 复制代码
Arrays.asList(1,2,3,4,5)
        .stream()
        .skip(2)
        .forEach(System.out::println);

输出:

复制代码
3
4
5

七、终结操作


1. forEach() 遍历

复制代码
stream.forEach(System.out::println);

2. count() 统计数量


示例

java 复制代码
long count =
        Arrays.asList(1,2,3,4)
                .stream()
                .count();

System.out.println(count);

输出:

复制代码
4

3. collect() 收集结果

最重要的方法之一。


示例:收集为 List

java 复制代码
import java.util.List;
import java.util.stream.Collectors;

public class Demo {

    public static void main(String[] args) {

        List<Integer> list =
                Arrays.asList(1,2,3,4,5)
                        .stream()
                        .filter(n -> n % 2 == 0)
                        .collect(Collectors.toList());

        System.out.println(list);
    }
}

输出:

复制代码
[2, 4]

八、Stream 完整案例


案例:处理学生成绩

需求:

复制代码
找出大于80分的成绩
按降序排序
取前3名

代码

java 复制代码
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Demo {

    public static void main(String[] args) {

        List<Integer> scores =
                Arrays.asList(90,75,88,60,95,85);

        List<Integer> result =
                scores.stream()
                        .filter(s -> s > 80)
                        .sorted((a,b) -> b - a)
                        .limit(3)
                        .collect(Collectors.toList());

        System.out.println(result);
    }
}

输出:

复制代码
[95, 90, 88]

九、Stream 与传统循环对比

对比 for循环 Stream
写法 繁琐 简洁
可读性 一般
链式操作 不支持 支持
函数式编程 不支持 支持

十、注意事项


1. Stream 只能使用一次

错误用法:

java 复制代码
Stream<String> stream = list.stream();

stream.forEach(System.out::println);

stream.forEach(System.out::println);

会报错,因为流已经关闭。


2. Stream 不会修改原数据

java 复制代码
list.stream().sorted();

不会改变原集合。


十一、小tips


1. Stream 是什么?

一种:

操作数据的流水线。


2. Stream 有什么优点?

  • 代码简洁

  • 支持链式编程

  • 函数式风格


3. 中间操作和终结操作区别?

类型 特点
中间操作 返回 Stream
终结操作 返回结果并结束流

十二、常用方法总结

方法 作用
filter 过滤
map 转换
sorted 排序
distinct 去重
limit 截取
skip 跳过
forEach 遍历
count 统计
collect 收集

十三、一张图理解 Stream

java 复制代码
集合数据
   ↓
stream()
   ↓
filter()
   ↓
map()
   ↓
sorted()
   ↓
collect()
   ↓
结果集合

十四、小结


Stream 核心思想

"像流水线一样处理数据"


Stream 最核心优势

复制代码
代码更简洁
逻辑更清晰
支持函数式编程

Stream 流,本质上就是 Java 用来"优雅处理集合数据"的工具。

相关推荐
满怀冰雪6 小时前
第04篇-双指针算法-从有序数组到回文判断的高频解法
java·算法
matlabgoodboy6 小时前
计算机java程序代写python代码编写c/c++代做qt设计php开发matlab
java·c语言·python
zh路西法6 小时前
【绕过 vscode-server】用 SSHFS SFTP 实现本地远程开发
ide·vscode·编辑器
小二·6 小时前
AI 代码审查 VSCode 插件实战
ide·人工智能·vscode
视觉小萌新7 小时前
C++利用libmicrohttpd制作交互网页端——C1
java·c++·交互
Gauss松鼠会7 小时前
【GaussDB】GaussDB SMP特性调优详解
java·服务器·前端·数据库·sql·算法·gaussdb
格发许可优化管理系统7 小时前
Mentor许可证使用规定全解析
java·大数据·c语言·开发语言·c++
AINative软件工程7 小时前
Tool Schema 写得好,模型少出错:5 个工程师必知的设计原则
后端·openai
AINative软件工程7 小时前
AI 写的代码,Review 要怎么改?我们团队的 15 条 PR 检查清单
后端·openai
JAVA面经实录9177 小时前
Redis 知识体系(完整版)
java·redis·nosql数据库·nosql