java学习笔记18-【Stream流、方法引用】

java8中得益于lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端
lambda 告诉我们应该更加专注于做什么而不是怎么做. for循环的语法就是怎么做,而它的循环体才是做什么

遍历是指每个元素逐一进行处理,这是目的 循环是从头到尾依次处理的循环,这是形式
当我们需要对集合中的元素进行操作的时候,总是循环循环再循环,这是理所当然的吗?不是 循环只是一种形式,并不是目的
另外使用线性循环意味着只能遍历一次,如果需要再次遍历就需要再使用另一个循环从头到尾循环一次

lambda的延迟执行特性
Stream流其实是一个集合元素的函数模型,它并不是集合也不是数据结构,其本身并不储存任何元素及其地址值.
Stream流是一个来自数据源的元素队列 元素是特定类型的对象,形成一个队列 java中的Stream并不存储数据,而是按需计算 数据源:流的来源 它可以使集合\数组等

Stream流还有两个基础的特征 1.pipelining:中间的操作都会返回流本身.这样多个操作可以串成一个管道,如同流式风格(fluent Style),这样做可以对操作进行优化,如延迟(laziness)和短路(shot-circuiting)
2.内部迭代(以前的for循环都是外部迭代),流可以直接调用遍历方法

每次转换原有的Stream对象不改变,返回一个新的Stream对象

java.util.stream.Stream 接口是java8新加入的最常用的流接口
获取流常用的方式 1.所有Collection集合都可以通过stream默认方法获取流 2.Stream接口的静态方法of可以获取数组对应的流

java.util.Collection接口中加入了default方法stream()来获取流,所以它的所有实现类都可以通过此方法获取流

Map接口的实现类需要分别获取key value 和entry的Stream

of方法的参数其实是一个可变参数,所以支持数组

流模型的操作很丰富,可分为两种,延迟类方法(返回值仍是Stream)和终结类方法(返回值不再是Stream,包括foreach和count方法)

常用方法:forEach 逐一处理 void forEach(Consumer<? super T> action) 该方法接收一个Consumer函数,将每一个流元素交给该函数处理
filter 可以将一个流转换成另一个子集流 Stream filter(Predicate<? super T> predicate) 该方法接收一个Predaicate函数式接口作为筛选条件

扫描二维码关注公众号,回复: 5895865 查看本文章

map映射,如果需要将流中的元素映射到另一个流,需要使用map方法 Stream map(Function<? super T,? extends R> function) 该方法需要一个Function类型的函数式接口参数,将流中T类型的数据转变换R类型的数据

count统计个数 该方法返回一个long类型的值,统计元素个数

limit取用前几个 可以对流中的元素进行截取只取用前n个 Stream limit(Long size)
skip跳过前几个元素,获取后面的元素,组成一个新流 Stream skip(long size) 如果流的长度小于n 那么返回一个空流

如果有两个流需要合并成一个流,可以使用Stream接口的静态方法concate static Stream concate(Stream<? extends T>a,Stream<? extends T>b)

::双冒号这种语法是方法引用 ::双冒号为引用运算符,而它所在的表达式被称为方法引用
如果lambda要表达的函数方案,已经存在于某个方法的实现中,那么则可以通过双冒号来引用该方法作为lambda的替代者
Lambda中传递的参数一定要是引用方法可以接收的数据类型,否则会抛出异常

Lambda中有可推导就是可省略的原则
函数式接口是lambda的基础,而方法引用是lambda的孪生兄弟

方法的引用 通过对象引用成员方法 通过类名引用静态方法 存在继承关系的时候,通过super引用父类的成员方法 本类中成员方法this引用 类的构造器引用 person::new 等同于 name->new Person(name)
数组构造器引用 length->new int[length] 等同于int[]::new

猜你喜欢

转载自blog.csdn.net/wwzzh1989/article/details/89209116
今日推荐