java学习笔记一-函数式接口&lambda表达式&方法引用&Stream流


是Java8的重要更新,Lambda表达式和方法引用最主要的功能是为流(专门负责迭代数据的集合)服务.lambda表达式和方法引用,只能用在函数式接口上.

1.函数式接口的简介

函数式接口在Java中是指:有且仅有一个抽象方法的接口.
与 @Override 注解的作用类似,Java 8中专门为函数式接口引入了一个新的注解: @FunctionalInterface 。该注解可用于一个接口的定义上:
@FunctionalInterface
public interface MyFunctionalInterface {
void myMethod();
}
一旦使用该注解来定义接口,编译器将会强制检查该接口是否确实有且仅有一个抽象方法,否则将会报错。不过,即使不使用该注解,只要满足函数式接口的定义,这仍然是一个函数式接口,使用起来都一样。
JDK提供了大量常用的函数式接口以丰富Lambda的典型使用场景,它们主要在 java.util.function 包中被提供。例如:Supplier供给型接口,Consumer消费型接口,Function函数型接口(转换),Predicate接口(判断)等.

2.1 什么是lambda表达式

Lambda表达式本质上是一个匿名方法,是匿名内部类的简化写法。Lambda的语法非常简洁,完全没有面向对象复杂的束缚。

2.2 使用限制:

  1. 重写一个函数式接口的方法时,可以使用lambda表达式.(函数式接口:就是有且仅有一个抽象方法的接口. )
    无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一时,才可以使用Lambda表达式。
  2. 使用Lambda必须具有上下文推断(使用接口当做方法参数或者使用接口接收Lambda),才能使用Lambda作为该接口的实例。
    备注:因为重写的肯定是这一个抽象方法,所以根据上下文推断可以省略方法修饰符,方法名,返回值类型…

2.3 Lambda的标准格式

Lambda省去面向对象的条条框框,格式由3个部分组成:
一些参数
一个箭头
一段代码
Lambda表达式的标准格式为:
(参数类型 参数名称) ‐> { 代码语句 }
格式说明:
小括号内的语法与传统方法参数列表一致:无参数则留空;多个参数则用逗号分隔。
-> 是新引入的语法格式,是运算符,代表指向动作。
大括号内的语法与传统方法体要求基本一致。

2.4 Lambda的省略格式:

省略规则
在Lambda标准格式的基础上,使用省略写法的规则为:

  1. 小括号内参数的类型可以省略;
  2. 如果小括号内有且仅有一个参,则小括号可以省略;
  3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。

3.1 什么是方法引用

方法引用是Lambda表达式的孪生兄弟, 方法引用是Lambda表达式的简化写法,是一个语法糖.

3.2 方法引用的使用前提

如果Lambda表达式(本质上是重写之后的匿名方法)拿到参数之后,【直接】对参数进行处理(意思是自己没有亲自对这个参数进行加工),那么我们可以使用一种更简单的写法,叫做方法引用.
方法引用符号是::,可以使用::去实现。

3.4 方法引用的常见的四种方式:

	1. 对象引用成员方法
	      对象名::方法名
	2. 类名引用静态方法
	      类名::静态方法
	3. 类的构造器引用
		类的构造器(类似于构造方法)引用要在创建对象的时候使用。
		 类名::new
	4. 数组的构造器引用
		 数组的构造器引用在创建数组的时候使用。
		 数据类型[]::new

4.1 Stream流

在Java 8中,得益于Lambda所带来的函数式编程,引入了一个全新的Stream概念,用于解决已有集合类库既有的弊端。
Stream 使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。
Stream API可以极大提高Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。
这种风格将要处理的元素集合看作一种流, 流在管道中传输, 并且可以在管道的节点上进行处理, 比如筛选, 排序,聚合等。
元素流在管道中经过中间操作(intermediate operation)的处理,最后由最终操作(terminal operation)得到前面处理的结果。
和以前的Collection操作不同, Stream操作还有两个基础的特征:

Pipelining: 中间操作都会返回流对象本身。 这样多个操作可以串联成一个管道, 如同流式风格(fluent style)。 这样做可以对操作进行优化, 比如延迟执行(laziness)和短路( short-circuiting)。
内部迭代: 以前对集合遍历都是通过Iterator或者For-Each的方式, 显式的在集合外部进行迭代, 这叫做外部迭代。 Stream提供了内部迭代的方式, 通过访问者模式(Visitor)实现。

4.2 获取流的方式:

java.util.stream.Stream 是Java 8新加入的最常用的流接口。(这并不是一个函数式接口。)在 Java 8 中, 集合接口有两个方法来生成流: ① stream() − 为集合创建串行流。 ② parallelStream() − 为集合创建并行流。
1. 通过Collection(单列)集合获取流
Stream stream(): 获取一个流对象
2. 通过Map(双列)集合获取流
通过Map集合获取流(了解),Map集合不能直接获取流对象, 只能间接获取, 有三种间接获取方式。
①. 先获取Map集合中的所有的key, 然后获取所有key的stream流
②. 先获取Map集合中的所有的value,然后获取所有value的stream流
③. 先获取Map集合中的所有的Entry(键值对), 获取所有entry的stream流。
3. 通过数组获取流
方式一:使用Stream的静态方法of完成(推荐, 因为参数不仅可以传递数组, 也可以传递任意个数据)
static Stream of(T… values): 根据一个数组获取一个stream流
方式二: 使用Arrays的静态方法stream完成
static Stream stream(T[] array) : 根据一个数组获取对应的stream流

4.3 操作流的常用方法

forEach:逐一处理, 终结方法,不支持链式调用
count:获取个数, 终结方法,不支持链式调用
filter:过滤, 函数拼接,非终结方法,支持链式调用
limit:获取前几个,函数拼接,非终结方法,支持链式调用
skip:跳过前几个,函数拼接,非终结方法,支持链式调用
concat:合并,函数拼接,非终结方法,支持链式调用
map:映射,函数拼接,非终结方法,支持链式调用

4.4 将流收集

4.4.1. 收集到集合

Stream中用于收集的方法:
R collect(Collector collector):可以将流中的数据收集到集合。 参数Collector表示收集到哪种集合。Collector是一个接口,如果要传递需要传递Collector实现类对象, 这个实现类对象不能由我们自己去new,要通过Collectors工具类的静态方法进行获取, 使用不同方法获取的Collector,表示收集到了不同的集合中。
static Collector toList():如果使用toList获取的Collector对象,表示将数据收集到List集合中。
static Collector toSet()::如果使用toSet获取的Collector对象,表示将数据收集到Set集合中。

4.4.2. 收集到数组

我们可以使用Stream中的toArray方法进行收集
Object[] toArray(): 将流中的数据收集到数组, 返回Object[]

4.5 Stream流的注意事项

注意:
1. stream流不会改变源对象.Stream流中的非终结方法返回的都是Stream对象, 返回的Stream是一个新的Stream
2. Stream流只能一次性使用,不能多次操作,否则会报错。
3. stream流本身不保存任何元素.便于理解可以把流看成容器,但是它不是容器.流本身不保存任何元素,他保存的是一些的中间操作步骤.
4. stream流操作时延迟执行的.当调用终结方法时,会顺序将操作步骤执行.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值