Lambda表达式
一、体验Lambda表达式
1.为什么会存在lambda表达式?
*匿名内部类是为了简化单个实现类而出现的
*lambda表达式的出现就是为了简化匿名内部类
二、Lambda表达式的标准格式
1.格式
(形式参数) -> {代码块}
2.格式分析
(形式参数):其实就是匿名内部类中重写抽象方法的形式参数
->: 表明当前的这个表达式是一个lambda表达式 //也可以说小箭头是我们lambda表达式的标志
{代码块}:其实就是匿名内部类中重写抽象方法后的方法体
//注意:从匿名内部类简化为Lambda表达式的过程中,真正对我们有用的是参数列表和方法体
三、Lambda表达式的省略模式
1.省略原则
可推导:根据上下文来进行推导
可省略:
2.省略的规则 //了解
(1)参数类型可以省略。但是有多个参数的情况下,不能只省略一个
(2)如果参数有且仅有一个,那么小括号可以省略
(3)如果代码块的语句只有一条,可以省略大括号和分号,和return关键字
//对于省略规则只要求我们能看懂就行,写的时候还是按照标准格式去写
四、Lambda表达式的注意事项(使用前提)
1.使用Lambda必须要有接口(类和抽象类都不行),并且要求接口中有且仅有一个抽象方法
2.必须有上下文环境,才能推导出Lambda对应的接口
根据局部变量的赋值得知Lambda对应的接口
Runnable r = () -> System.out.println("Lambda表达式");
根据调用方法的参数得知Lambda对应的接口
new Thread(() -> System.out.println("Lambda表达式")).start();
五、Lambda表达式和匿名内部类的区别 //面试题
1.所需类型不同
*匿名内部类:可以是接口,也可以是抽象类,还可以是具体类 //使用更加广泛
*Lambda表达式:只能是接口
2.使用限制不同
*如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
*如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
3.实现原理不同
*匿名内部类:编译之后,产生一个单独的.class字节码文件 //在硬盘上
*Lambda表达式:编译之后,没有一个单独的.class字节码文件。对应的字节码会在运行的时候动态生成 //在内存中
//Outer$Inner.class
$是用来分隔内部类中外部类和内部类
//注意:以后在命名类名的时候,千万不要出现$符号
接口的组成更新 //了解
一、接口的更新
1.jdk7及其以前
接口里面只能有常量和抽象方法
2.jdk8
添加了静态方法和默认方法
3.jdk9
添加了私有方法
二、接口中的默认方法
1.格式
public default 返回值 方法名(参数列表){
xxxxxxxxxxxx
}
*默认方法不是抽象方法,是有方法体的
*初学者不建议省略public
2.应用场景
接口升级
3.接口中的方法使用场景
抽象方法:项目刚开始的设计阶段,这个时候由于还没有写实现类,多加一个抽象方法对原有代码不会有影响,这个时候使用抽象方法
默认方法:项目的中后期,接口需要升级的时候,我们可以添加默认方法
三、接口中的静态方法
1.格式
public static 返回值 方法名(参数列表){
xxxxxxxxxxxxxxxxxx
}
2.注意事项
(1)接口中的静态方法只能被接口名调用,不能通过实现类名或者对象名调用
(2)public可以省略,而static不能省略
3.应用场景
工厂模式解耦合
四、接口中的私有方法
//在jdk9出现的
1.格式
*private 返回值类型 方法名(参数列表) { } //普通私有方法
*private static 返回值类型 方法名(参数列表) { } //私有静态方法
2.注意事项
默认方法:可以调用静态的私有方法,也可以调用非静态的私有方法
静态方法:可以调用静态的私有方法
3.使用场景
接口中的私有方法是给接口本身使用的,外界是无法使用的。
主要功能时为了消除静态方法和默认方法中的重复代码。
方法引用 //替代思想(方法替代方法)
一、体验方法引用
1.核心思想
就是拿已经存在的方法,替代你要重写的那个抽象方法的实现方法
2.格式分析
System.out::println
* System.out :是调用替代方法的调用者
* :: 表明当前的表达式是一个方法引用表达式 // ::就是我们方法引用的标志
* println :就是用来替代你要重写的那个方法
二、引用类方法
//类方法:其实就是指的静态方法
1.格式
类名::静态方法
*范例
Integer::parseInt
Integer类的方法:public static int parseInt(String s) 将此String转换为int类型数据
三、应用实例方法
//实例方法指的是非静态方法
1.格式
对象::非静态方法
*范例
"HelloWorld"::toUpperCase
String类中的方法:public String toUpperCase() 将此String所有字符转换为大写
四、引用类的实例方法 //了解
类:静态
实例方法:非静态方法
1.格式
类名::非静态方法
String substring(int beginIndex, int endIndex) 返回一个字符串,该字符串是此字符串的子字符串。
*举例:
String::sunstring
//Lambda表达式被类的实例方法替代的时候 第一个参数作为调用者 后面的参数全部传递给该方法作为参数
*对比
//Lambda简化写法
useMyString((s,x,y) -> s.substring(x,y));
//引用类的实例方法
useMyString(String::substring);
五、引用构造器
1.格式:
类名::new
*范例
Student::new
Lambda表达式被构造器替代的时候,它的形式参数全部传递给构造器作为参数
//方法引用小总结:
第一点:思想上的转变
*以前:你要什么,我就给你new什么
*现在:去找一个返回值、参数、功能和你需要实现的那个方法一模一样的方法 去代替它
第二点:最常用的方法引用 //最常见
1.直接打印
(String s)->{
System.out.parseInt(s);
}
------------------------------------
System.out::println
2.字符串转int
(String s)->{
return Integer.parseInt(s);
}
---------------------------------
Integer::parseInt