Stream 流
一、概述
流式思想(Stream)类似于工厂车间的生产流水线,Stream 流不是一种数据结构,不保存数据,而是对数据进行加工处理,Stream 流可以看作是流水线上的一个工序,通过多个工序让一个原材料加工成一个商品
二、获取 Stream 流的常用方式
1、集合接口 Collection 的默认方法 stream()
2、Stream 类中的静态方法
3、测试
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | public class StreamDemo { public static void main(String[] args) { List<Person> personList = Arrays.asList( new Person( 1 , "大毛" , 30 , 175 ), new Person( 1 , "二毛" , 25 , 170 ), new Person( 1 , "三毛" , 25 , 170 ), new Person( 1 , "小毛" , 20 , 163 )); // 获取流的方式一、Collection 集合接口的 stream() 方法 Stream<Person> personStream1 = personList.stream(); // 获取流的方式二、Stream 类的静态方法 of() Stream<Person> personStream2 = Stream.of( new Person( 1 , "大毛" , 30 , 175 ), new Person( 1 , "二毛" , 25 , 170 ), new Person( 1 , "三毛" , 25 , 170 ), new Person( 1 , "小毛" , 20 , 163 )); } } |
三、Stream 常用方法简介及注意事项
1、常用方法
Stream 提供了众多的 API,这些方法可以分为两类
- 终结方法: 返回值不是 Stream 类型的方法,不再支持链式调用
- 函数拼接: 返回值类型仍然是 Stream 类型的方法(注意这里返回的 Stream 是一个新流),支持链式调用
方法名 | 方法作用 | 返回值类型 | 方法类型 |
count | 统计数量 | long | 终结方法 |
foreach | 遍历处理 | void | 终结方法 |
filter | 过滤处理 | Stream | 函数拼接 |
limit | 取前几个数据 | Stream | 函数拼接 |
2、注意事项
- Stream 流只能操作一次
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class StreamDemo { public static void main(String[] args) { List<Person> personList = Arrays.asList( new Person( 1 , "大毛" , 30 , 175 ), new Person( 1 , "二毛" , 25 , 170 ), new Person( 1 , "三毛" , 25 , 170 ), new Person( 1 , "小毛" , 20 , 163 )); // 获取流、Collection 集合接口的 stream() 方法 Stream<Person> personStream = personList.stream(); // 第一次使用 Stream 流对象 Stream<Person> limit = personStream.limit( 1 ); // 第二次使用 Stream 流对象 personStream.filter((item)-> Objects.equals(item.getAge(), 25 )); } } |
可以看到,同一个 Stream 对象使用两次报错了
- Stream 返回的是一个新的流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | @Slf4j public class StreamDemo { public static void main(String[] args) { List<Person> personList = Arrays.asList( new Person( 1 , "大毛" , 30 , 175 ), new Person( 1 , "二毛" , 25 , 170 ), new Person( 1 , "三毛" , 25 , 170 ), new Person( 1 , "小毛" , 20 , 163 )); // 获取流、Collection 集合接口的 stream() 方法 Stream<Person> personStream = personList.stream(); // 第一次使用 Stream 流对象 Stream<Person> personLimitStream = personStream.limit( 1 ); log.info( "第一个 Stream 对象: {}" ,personStream); log.info( "第二个 Stream 对象: {}" ,personLimitStream); } } |
从上面的结果可以得知两个 Stream 对象不是同一个对象
- Stream 不调用终结方法,中间的操作不会执行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | @Slf4j public class StreamDemo { public static void main(String[] args) { List<Person> personList = Arrays.asList( new Person( 1 , "大毛" , 30 , 175 ), new Person( 1 , "二毛" , 25 , 170 ), new Person( 1 , "三毛" , 25 , 170 ), new Person( 1 , "小毛" , 20 , 163 )); // 获取流、Collection 集合接口的 stream() 方法 Stream<Person> personStream = personList.stream(); Stream<Person> personStream2 = personStream.filter((item) -> { log.info( "过滤出年龄等于 20 的毛毛" ); boolean equals = Objects.equals(item.getAge(), 20 ); return equals; }); } } |
上述代码无任何输出结果
让 Stream 调用终结方法 collect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | @Slf4j public class StreamDemo { public static void main(String[] args) { List<Person> personList = Arrays.asList( new Person( 1 , "大毛" , 30 , 175 ), new Person( 1 , "二毛" , 25 , 170 ), new Person( 1 , "三毛" , 25 , 170 ), new Person( 1 , "小毛" , 20 , 163 )); // 获取流、Collection 集合接口的 stream() 方法 Stream<Person> personStream = personList.stream(); List<Person> collect = personStream.filter((item) -> { log.info( "过滤出年龄等于 20 的毛毛" ); boolean equals = Objects.equals(item.getAge(), 20 ); return equals; }).collect(Collectors.toList()); log.info( "输出结果: {}" , JSONObject.toJSONString(collect)); } } |
输出结果如下,可以看到 filter() 方法中的代码执行了
四、Stream 流常用 API
方法名 | 方法作用 | 参数 | 返回值 | 方法类型 | 详细案例 |
foreach | 遍历流中每一个元素,交给 Consumer 函数进行处理 |
Consumer<? super T> action |
void | 终结方法 | https://www.cnblogs.com/xiaomaomao/p/16468015.html |
count | 统计流中元素的个数 | long | 终结方法 | https://www.cnblogs.com/xiaomaomao/p/16471312.html | |
filter | 过滤流中符合条件的数据,返回值为 true 代表符合条件的数据 | Predicate<? super T> predicate | Stream | 函数拼接 | https://www.cnblogs.com/xiaomaomao/p/16471368.html |
limit | 截取流中前 maxSize 个元素,maxSize 大于总数,则截取所有元素 | long maxSize | Stream | 函数拼接 | https://www.cnblogs.com/xiaomaomao/p/16471417.html |
skip | 跳过前 n 个元素,截取流中剩余的元素,如果 n 大于等于当前流的长度,则返回一个空流 | long n | Stream | 函数拼接 | https://www.cnblogs.com/xiaomaomao/p/16471518.html |
map | 将 T 类型的流转换成 R 类型的流 | Function<? super T, ? extends R> mapper | Stream | 函数拼接 | https://www.cnblogs.com/xiaomaomao/p/16471571.html |
sorted(...) | 对流中元素进行排序(支持自然排序和定制排序) | 无参 / Comparator<? super T> comparator | Stream | 函数拼接 | https://www.cnblogs.com/xiaomaomao/p/16471802.html |
distinct | 对流中元素进行去重 | Stream | 函数拼接 | https://www.cnblogs.com/xiaomaomao/p/16471921.html | |
match | allMatch、noneMatch、anyMatch(判断元素是否匹配指定条件) | Predicate<? super T> predicate | boolean | 终结方法 | https://www.cnblogs.com/xiaomaomao/p/16493073.html |
max、min | 获取最大、最小值 | Comparator<? super T> comparator | Optional | 终结方法 | https://www.cnblogs.com/xiaomaomao/p/16493180.html |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2021-07-19 Mybatis 比较时间日期