Java8新特性——————Lambda表达式,函数式(Functional)接口,方法引用与构造器引用
Java8新特性的简介
①,速度更快
②,代码更少(增加了新的语法:Lambda 表达式)
③,强大的 Stream API
④,便于并行
⑤,最大化减少空指针异常:Optional
Lambda表达式
- 1,为什么要使用Lambda表达式 ?
Lambda 是一个 匿名函数,我们可以把 Lambda 表达式理解为是 一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。
- 2,Lambda表达式的使用
举例:(o1,o2)-> Integer.compare(o1,o2);
格式:
->:lamdba操作符或箭头操作符
->左边:lamdba形参列表(其实就是接口中的抽象方法的形参列表)
->右边:lamdba体(其实就是重写的抽象方法的方法体)
- 3,从匿名类到Lambda的转换举例
@Test
public void test1(){
Runnable r1 = new Runnable() {
@Override
public void run() {
System.out.println("Hello World!");
}
};
r1.run();
Runnable r2 = () -> System.out.println("Hello Lambda!");
r2.run();
}
@Test
public void test2(){
Comparator<Integer> com1 = new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return Integer.compare(o1,o2);
}
};
int compare1 = com1.compare(12,13);
System.out.println(compare1);//-1
//Lambda表达式的写法
Comparator<Integer> com2 = (o1,o2) -> Integer.compare(o1,o2);
int compare2 = com2.compare(14,13);
System.out.println(compare2);//1
//方法引用
Comparator<Integer> com3 = Integer :: compare;
int compare3 = com3.compare(14,13);
System.out.println(compare3);//1
}
- 4,Lambda表达式的语法格式
①,Lamdba语法格式一 :
Runnable r1 = () -> {System.out.printn("Hello Lambda!");};
②,语法格式二: :Lambda 需要一个参数,但是没有返回值。
Consumer<String> con = (String str) -> {System.out.printn(str);};
③,语法格式三 : 数据类型可以省略 ,因为可由编译器推断得出,称为“类型推断”
Consumer<String> con= (str) -> {System.out.printn(str);};
④,语法格式四: :Lambda 若只需要一个参数时,参数的小括号可以省略
Consumer<String> con = str -> {System.out.printn(str);};
⑤,语法格式五: :Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值
Comparator<Integer> com= (x,y) -> {
System.out.printn("实现函数式接口方法! ");
return Integer.compare(x,y);
};
⑥,语法格式六 :当 Lambda 体只有 一条, 语句时,return 号 与大括号
Comparator<Integer> com= (x,y) -> Integer.compare(x, y);
总结:
->左边: lambda形参列表的参数类型可以省略(类型判断);如果lambda形参列表只有一个参数,其一对()也可以省略
->右边: lambda体应该使用一对{}包裹;如果lambda体只有一条执行语句(可能是return语句),可以省略这一对{}和return关键字
函数式(Functional)接口
-
1,Lambda表达式的本质:作为函数式接口的实例
-
2,如果一个接口,只声明一个抽象方法,则此接口就称为函数式接口,我们可以在一个接口上使用@FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口,用匿名实现类表示的现在都可以用Lambda表达式来写
-
3,Java内置的4个核心函数式接口
例如:
@Test
public void test3(){
List<String> list = Arrays.asList("北京","南京","天津","牛津","东经","西经");
List<String> filterStrs = filterString(list, new Predicate<String>() {
@Override
public boolean test(String s) {
return s.contains("京");
}
});
System.out.println(filterStrs);
//Lambda表达式的写法
List<String> filterStrs1 = filterString(list,s -> s.contains("京"));
System.out.println(filterStrs1);
}
//根据给定的规则,过滤集合中的字符串。此规则由Predicate的方法决定
public List<String> filterString(List<String> list, Predicate<String> pre){
ArrayList<String> filterList = new ArrayList<>();
for(String s : list){
if (pre.test(s)){
filterList.add(s);
}
}
return filterList;
}
-
4,其他接口
方法引用
-
1,使用情景:当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用
-
2,方法引用,本质上就是Lambda表达式,而Lambda表达式作为函数式接口的实例。所以方法引用,也是函数式接口的实例
-
3,使用格式:类(或对象):: 方法名
-
4,具体分为如下的三种情况
对象 :: 非静态方法 类 :: 静态方法 类 :: 非静态方法
-
5,方法引用使用的要求:要求接口中的抽象方法的形参列表和返回值类型与方法引用的方法形参列表和返回值类型相同
例如:
Employee emp = new Employee( 1001, "Tommey", 23, 5600);
Supplier<String> sup1 = () -> emp . getName();
System.out.print1n(sup1.get());//Tommey
Supplier<String> sup2 = emp :: getName;
System.out.println(sup2.get());//Tommey
构造器引用
- 1,和方法引用类似,函数式接口的抽象方法的形参列表和构造器的形参列表一致
抽象方法的返回值类型即为构造器所属的类的类型 -
2,格式:ClassName :: new数组引用
数组引用
-
1,格式: type[] :: new数组引用
推荐阅读
-
[Java笔记]动态代理、lambda表达式、函数式接口、构造器引用
-
java8新特性lambda表达式、函数式编程、方法引用和接口默认方法以及内部类访问外部变量
-
Java8新特性——————Lambda表达式,函数式(Functional)接口,方法引用与构造器引用
-
【Java 20】Java8的其他新特性 - Lambda表达式、函数式接口、方法引用、构造器引用、数组引用、Stream API、Optional类
-
快速学习Java8新特性第四讲——方法引用与构造器引用
-
java8新特性总结——lambda表达式之方法引用与构造器引用
-
JAVA8核心语法梳理(1)Lambda表达式、函数式接口、方法引用
-
[Java笔记]动态代理、lambda表达式、函数式接口、构造器引用
-
Java8新特性 - (方法引用与构造器引用)
-
java8新特性之方法引用与构造器引用+Stream