Java8 Lambda表达式
出现的背景
Java是面向对象的语言,除了部分简单基本数据类型,Java中的一切都是对象。在Java中定义的函数或方法不可能完全独立,也不能将方法作为参数或返回一个方法给实例。
在Java8以前,我们想要把某些功能传递给某个方法,总要去写匿名类。比如为了对集合进行排序,我们为Comparator接口创建了一个它的匿名内部类对象,重写接口中的方法,来实现排序功能,所以在Java里将普通的方法或函数像参数一样传值并不简单,因此,Java 8增加了一个语言级的新特性,名为Lambda 表达式。
Lambda表达式简介
Lambda表达式是一个匿名函数,我们可以把lambda表达式理解为一段可以传递的代码(将代码段像数据一样传递)。使用它可以写出更简洁,更灵活的代码,使Java语言的表达能力得到提升。
Lambda表达式本质只是一个"语法糖(对语法进行简化)",由编译器推断并帮你转换包装常规的代码
Lambda表达式的结构
-
Lambda表达式可以具有零个,一个或多个参数
-
可以显式声明参数的类型,也可以由编译器自动从上下文推断参数的类型,例如(int a,int b)与(a,b)相同
-
参数用小括号括起来,用逗号分隔。例如(a,b)或(int a,int b)或(String a,int b,float c)。
-
空括号用于表示一组空的参数。例如() -> 42.
-
当有且仅有一个参数时,如果不显示指明类型,则可以不使用小括号
-
Lambda表达式的正文只有一条语句,则大括号可不用写,且表达式的返回值类型要与匿名函数的返回类型相同
-
如果Lambda表达式的正文有一条以上的语句必须包含在大括号(代码块)中,且表达式的返回值类型要与匿名函数的返回类型相同。
什么是功能接口
功能接口(Functional interface)
Lambda表达式只支持函数式接口,也就是只有一个抽象方法的接口。功能接口是Java8中新增的功能,他们只允许一个抽象方法。这些接口也称为但抽象方法接口。Java8也引入注释@Functional Interface,当你注释的接口违反契约时,它可以用于编译器级错误
Java8 Stream
Stream时Java8的新特性,它允许你以声明式的方式处理数据集合,可以把它看作是遍历数据集的高级迭代器。
什么是Stream
从支持数据处理操作的源,生成的元素序列
元素列表:和集合一样,流也提供了一个接口,访问特定元素类型的一组有序值。
数据源:获取数据的源,比如集合
数据处理操作:流更偏向于数据处理和计算,比如filter、map、find、sort等。
我们通过一个集合的stream方法获取一个流,然后对流进行一系列流操作,最后在构建成我们需要的数据集合。
获取流
使用Collection接口下的stream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream();
使用Arrays中的stream()方法,将数组转为流
Integer[] nums = new Integer[10];
Stream<Integer> stream = Arrays.stream(nums);
使用Stream中的静态方法:of()
Stream<Integer> stream = Stream.of(1,2,3,4,5);
使用BufferedReader.lines()方法,将每行内容转成流
BufferedReader reader = new BufferedReader(new FileReader("stream.txt"));
Stream<String> lineStream = reader.lines();
流操作
流操作可以分为两类:中间操作和终端操作
集合/数组 ---> Stream ---> 中间操作(过滤,去重,排序...)---> Stream--->(过滤,去重,排序...)--->终端操作(需要的数据)
1.获取流
2.中间操作(可选)
3.终端操作
支持链式操作
中间操作
filter: 过滤流中的某些元素
sorted(): 自然排序,流中元素需实现Comparable接口
distinct():去除重复元素
limit(n):获取n个元素
skip(n):跳过n个元素,配合limit(n)实现分页
map(): 将其映射成一个新的元素
终端操作
forEach: 遍历流中的元素
toArray:将流中的元素导入一个数组
Min:返回流中元素最小值
Max:返回流中元素最大值
count: 返回流中元素的总个数
Reduce:所有元素求和
anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足条件则返 回 true,否则返回 false
allMatch:接收一个 Predicate 函数,当流中每个元素都符合条件时才返 回 true,否则返回 false
findFirst:返回流中第一个元素
collect:将流中的元素导入一个集合,Collection或Map