小新学Java19-【Stream流、方法引用】
一、Stream流
1.1引言
传统集合的多步遍历
代码循环遍历的弊端
Stream的更优写法
1.2流式思想概述
这里的filter 、map 、skip都是在对函数模型进行操作,集合元素并没有真正被处理。只有当终结方法 count执行的时候,整个模型才会按照指定策略执行操作。而这得益于Lambda的延迟执行特性。
备注:"Stream流"”其实是一个集合元素的函数模型,它并不是集合,也不是数据结构,其本身并不存储任何元素(或其地址值)。
Stream(流)是一个来自数据源的元素队列
✦元素是特定类型的对象,形成一个队列。Java中的Stream并不会存储元素,而是按需计算。
✦数据源:流的来源。可以是集合,数组等。
和以前的Collection操作不同,Stream操作还有两个基础的特征∶
✦Pipelining:中间操作都会返回流对象本身。这样多个操作可以串联成一个管道,如同流式风格( fluentstyle )。这样做可以对操作进行优化,比如延迟执行(laziness)和短路( short-circuiting)。
✦内部迭代︰以前对集合遍历都是通过lterator或者增强for的方式,显式的在集合外部进行迭代,这叫做外部迭代。Stream提供了内部迭代的方式,流可以直接调用遍历方法。
当使用一个流的时候,通常包括三个基本步骤∶获取一个数据源(source )→数据转换→执行操作获取想要的结果,每次转换原有Stream对象不改变,返回一个新的Stream对象(可以有多次转换),这就允许对其操作可以像链条一样排列,变成一个管道。
1.3获取流
java.util.stream.Stream<T>是Java 8新加入的最常用的流接口。(这并不是一个函数式接口。)
获取一个流非常简单,有以下几种常用的方式:
-所有的Collection集合都可以通过Stream默认方法获取流;
default Stream<E> stream()
-Stream接口的静态方法of可以获取数组对应的流。
static <T> Stream<T> of (T... values)
参数是一个可变参数,那么我们就可以传递一个数组
根据Collection获取流
根据Map获取流
根据数组获取流
1.4常用方法
过滤:filter
Stream流中的常用方法_filter:用于对Stream流中的数据进行过滤
Stream<T> filter( Predicate<? super T> predicate);
filter方法的参数Predicate是一个函数式接口,所以可以传递Lambda表达式,对数据进行过滤
Predicate中的抽象方法:
boolean test(T t);
复习Predicate接口基本使用
统计个数:count
Stream流中的常用方法_count:用于统计stream流中元素的个数
long count( );
count方法是一个终结方法:返回值是一个long类型的整数所以不能再继续调用Stream流中的其他方法了
取用前几个:limit
Stream流中的常用方法_limit:用于截取流中的元素
limit方法可以对流进行截取,只取用前n个。
方法签名:Stream<T> limit(long maxSize);
参数是一个long型,如果集合当前长度大于参数则进行截取;否则不进行操作
limit方法是一个延迟方法,只是对流中的元素进行截取,返回的是一个新的流,所以可以继续调用Stream流中的其他方法
跳过前几个:skip
Stream流中的常用方法_skip:用于跳过元素
如果希望跳过前几个元素,可以使用skip方法获取一个截取之后的新流:Stream<T> skip(long n);
如果流的当前长度大于n,则跳过前n个;否则将会得到一个长度为0的空流。
映射: map
如果需要将流中的元素映射到另一个流中,可以使用map方法。
<R> Stream<R> map(Function<? super T, ? extends R> mapper );
该接口需要一个Function函数式接口参数,可以将当前流中的T类型数据转换为另一种R类型的流。
Function中的抽象方法:
apply (T t);
复习Function接口基本使用
组合:concat
Stream流中的常用方法_concat:用于把流组合到一起
如果有两个流,希望合并成为一个流,那么可以使用Stream接口的静态方法concat
static <T> Stream<T> concat(Stream<? extends T> a,Stream<? extends T> b)
逐一处理: forEach
Stream流中的常用方法forEach
void forEach(Consumer< ? super T> action);
该方法接收一个Consumer接口函数,会将每一个流元素交给该函数进行处理。
Consumer接口是一个消费型的函数式接口,可以传递Lambda表达式,消费数据
简单记:
forEach方法,用来遍历流中的数据
是一个终结方法,遍历之后就不能外继续调用Stream流中的其他方法
1.5练习:
集合元素处理(传统方式)
二、方法引用
2.1冗余的Lambda场景
2.2问题分析
2.3用方法引用改进代码
2.4方法引用符语义分析
推导与省略
2.5通过对象名引用成员方法
通过对象名引用成员方法
使用前提是对象名是已经存在的,成员方法也已经存在
就可以使用对象名来引用成员方法
2.6通过类名称引用静态方法
通过类名引用静态成员方法
类已经存在,静态成员方法也已经存在
就可以通过类名直接引用静态成员方法
2.7通过super引用成员方法
使用super引用类的成员方法super是已经存在的
父类的成员方法sayHello也是已经存在的
所以我们可以直接使用super引用父类的成员方法
2.8通过this引用成员方法
this是已经存在的
本类的成员方法buy也已经存在
所以可以通过this引用本类成员方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!