Java8 Stream流入门笔记|极简上手,告别繁琐for循环
(封面描述:Java8 Stream流核心用法总结,包含Lambda表达式、Stream常用方法,适合Java新人入门,代码清晰可直接复制运行)
标签:#Java #Java8 #Stream流 #Lambda表达式 #Java后端 #新手入门
1. 什么是 Stream?
Stream 是 Java 8 基于 Lambda 表达式推出的集合操作简化写法。
它的核心作用:用极简代码对集合进行遍历、过滤、转换、统计等操作,告别繁琐的 for 循环。
一句话理解:
Stream = 集合的现代化流水线操作
2. 前置知识:Lambda 表达式
Stream 必须配合 Lambda 使用,所以先快速回顾 Lambda 的核心用法,新手也能秒懂。
Lambda 本质
对只有一个抽象方法的接口(函数式接口) 进行简化,省略冗余代码,让代码更简洁。
使用前提
- 接口有且仅有一个抽象方法
- 能通过上下文推断接口和方法类型,无需手动声明
示例对比(匿名内部类 VS Lambda)
// 匿名内部类(传统写法,繁琐)
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("创建一个线程");
}
}).start();
// Lambda 表达式(极简写法,核心逻辑一目了然)
new Thread(() -> System.out.println("创建一个线程")).start();
Lambda 核心规则
- 省略接口名、方法名、@Override 注解(上下文可推断)
()中放置方法参数(无参数则留空,单参数可省略括号)->分隔参数与方法体,意为“执行”- 方法体只有一行代码时,
{}和;可以省略
3. 获取 Stream 流的三种方式(必会)
日常开发中,前两种最常用,第三种适合快速创建简单流。
(1)通过集合获取(最常用)
List<String> list = new ArrayList<>();
// 集合对象直接调用 stream() 方法
Stream<String> stream = list.stream();
(2)通过数组获取
String[] arr = {"a", "b", "c"};
// 借助 Arrays 工具类的 stream() 方法
Stream<String> stream = Arrays.stream(arr);
(3)通过 Stream.of() 静态方法(快速创建)
// 直接传入元素,快速创建流
Stream<String> stream = Stream.of("a", "b", "c");
流的两种类型(补充)
- 串行流:默认类型,单线程处理,顺序执行(stream() 方法获取)
- 并行流:多线程处理,适合大数据量,效率更高(parallelStream() 方法获取)
4. Stream 常用方法(必背,附实例)
Stream 方法分为两类,核心区别:是否会消耗流(消耗后无法再次使用)。
- 延迟方法:返回值仍然是 Stream 类型,可链式调用,不立即执行
- 终结方法:执行后流被消耗,无法再使用,会触发所有延迟方法的执行
(1)forEach() —— 遍历流(终结方法,最常用)
作用:对流中的每一个元素进行处理(最常见场景:打印输出)。
List<String> list = Arrays.asList("张三", "李四", "王二");
// 方式1:Lambda 写法
list.stream().forEach(name -> System.out.println(name));
// 方式2:方法引用写法(更简洁,推荐)
list.stream().forEach(System.out::println);
(2)filter() —— 条件过滤(延迟方法)
作用:筛选出符合指定条件的元素,返回新的流。
List<String> list = Arrays.asList("张三", "王五", "李四", "张销售");
// 需求:过滤出所有姓张的名字,然后打印
list.stream()
.filter(name -> name.startsWith("张")) // 过滤条件:以“张”开头
.forEach(System.out::println); // 链式调用,遍历输出
(3)map() —— 类型转换(映射,延迟方法)
作用:将流中元素的类型转换为另一种类型(比如 String 转 int)。
List<String> list = Arrays.asList("1", "2", "3", "4");
// 需求:将 String 类型的数字,转换为 int 类型并打印
list.stream()
.map(str -> Integer.parseInt(str)) // 转换逻辑:String → int
.forEach(System.out::println);
(4)count() —— 统计数量(终结方法)
作用:统计流中元素的个数,类似集合的 size() 方法,返回 long 类型。
List<String> list = Arrays.asList("1", "2", "3", "4");
long count = list.stream().count(); // 统计元素个数
System.out.println("元素个数:" + count);
(5)limit() —— 取前 N 个元素(延迟方法)
作用:限制流中元素的数量,只保留前 N 个。
List<String> list = Arrays.asList("1", "2", "3", "4");
// 需求:只保留前 3 个元素并打印
list.stream()
.limit(3) // 保留前3个
.forEach(System.out::println);
(6)skip() —— 跳过前 N 个元素(延迟方法)
作用:跳过流中前 N 个元素,保留后面的元素。
List<String> list = Arrays.asList("1", "2", "3", "4");
// 需求:跳过前 3 个元素,打印剩下的
list.stream()
.skip(3) // 跳过前3个
.forEach(System.out::println);
(7)concat() —— 拼接两个流(静态方法)
作用:将两个流合并为一个新的流,方便统一处理。
// 创建两个流
Stream<String> stream1 = Stream.of("1", "3");
Stream<String> stream2 = Stream.of("2", "4");
// 拼接两个流,得到新流并打印
Stream<String> newStream = Stream.concat(stream1, stream2);
newStream.forEach(System.out::println);
5. Stream 总结(新人易懂版)
学完 Stream 你会发现,它和数据库的查询操作非常像,新手可以这样类比记忆:
- filter() → 类似 SQL 中的 where 条件过滤
- limit()/skip() → 类似 SQL 中的分页(limit N, offset N)
- map() → 类似 SQL 中的字段转换(比如 cast 函数)
- concat() → 类似 SQL 中的表关联(union)
- forEach() → 类似 SQL 中的 select 输出结果
Stream 最大的优势:用最少的代码完成集合的各种操作,摆脱繁琐的 for 循环和判断,代码更优雅、更易读、更符合现代 Java 开发规范。
✨ 新手建议:把上面的代码复制到 IDE 中,逐一运行,感受 Stream 的简洁性,多练2遍就能熟练上手!