lambda表达式
语法规则
- 无参数,无返回值
()-> System.out.println("Hello Lambda!")
- 有一个参数,并且无返回值
(x)-> System.out.println(x)
- 若只有一个参数,小括号可以省略不写
x-> System.out.println(x)
- 有两个以上的参数,有返回值,并且 Lambda体中有多条语句
Comparator<Integer> com =(x,y)->{ (System.out.print1n("函数式接口"); return Integer.compare(x,y); }
- 若 Lambda体中只有一条语句, return和大括号都可以省略不写
Comparator<Integer> com =(x,y) -> Integer. compare (x,y)
- Lambda表达式的参数列表的数据类型可以省略不写,编译器通过上下文推断出,数据类型,即“类型推断”
(Integer x, Integer y)-> Integer. compare(x, y)
java8新特性
List list = new ArrayList();
list.forEach(a->System.out.print(a));
java1.8升级后加入很多特性,lambda就是其中一个,lambda可以简化代码的编写。
代替匿名内部类
public class Run {
public static void main(String[] args) {
P p = new P();
int moeny = 1000;
p.test(moeny,new Person(){
@Override
public void buy() {
System.out.println("我花了" + moeny + "元");
}
});
}
}
interface Person{
void buy();
}
class P{
int money;
public void test(int money,Person person){
System.out.println("测试lambda表达式");
person.buy();
}
}
当这种情况不多的时候就可以用匿名内部类,而不需要实现实体类。这个时候就可以用lambda表达式代替
public class Run {
public static void main(String[] args) {
P p = new P();
int moeny = 1000;
//替换
p.test(moeny,()->System.out.println("我花了" + moeny + "元"));
}
}
interface Person{
void buy();
}
class P{
int money;
public void test(int money,Person person){
System.out.println("测试lambda表达式");
person.buy();
}
}
个人理解lambda解析
lambda的本质就是对象,重写接口的方法,所以该删的删一删 经过编译器的特殊编译。
以Arraylist中foreach举例 解析lambda
public class Main {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
Integer arr[] ={1,2,3,4,5};
list.addAll(Arrays.asList(arr));
list.forEach(a->System.put.println(a));
}
}
首先forEach方法是jdk1.8在Iterable接口中加的一个方法
ArrayList继承关系图
DeBug断点进入,可以清楚看到ArrayList原码中循环调用了消费模式接口中的accept方法,而lambda的本质又是一个函数时接口的子类对象,重写了函数时接口的哪一个唯一的抽象方法,所以循环执行的是lambda重写的那一段代码。
函数式接口
定义
只能由一个抽象方法的接口 ,但是可以有多个default、static方法(jdk1.8加入)
4种重要函数式接口
@FunctionalInterface 注解意为函数式接口
接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer(消费型接口) | T | void | 对类型为T的对象应用操作,void accept(T t) |
Supplier 供给型接口 | 无 | T | 返回类型为T的对象,T get(); |
Function<T, R> 函数型接口 | T | R | 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t); |
Predicate 断定型接口 | T | boolean | 类型为T的对象是否满足某约束,并返回boolean 值。包含方法boolean test(T t) |
当然还有很多函数式接口 但这4种是比较常见的4中类型
为什么jdk1.8接口中新增default类型方法
在jdk1.8中新引入的lambda表达式,并且新增加了许多的方法,比如Iterable中的forEach方法,在1.8种要在很多的接口中添加很多的方法。如果添加public abstract 类型的方法,那么我们所有的实现类都要更改,来实现接口中所添加的方法,这样开发者就加了default这样的方法,实现类可以不需要重写default修饰的方法。就解决了问题,做到了版本跟新迭代的向上兼容。
lambda内部原理解析
class字节码解析
**如果对您有帮助点个赞呗
另外这里帮你准备了一些关于java和计算机方面的电子书 和相关面试题,并且会持续更新
关注公众号回复 电子书,面试题 即可领取并有各种学习资源
公众号内也会持续发布一些关于技术栈,学习,笔记等
公众号里面没找到你想要的可以后台回复哦,只要我有,就会给你
**
————————————————
版权声明:本文为CSDN博主「559Jiang」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43988251/article/details/121578334