lambda表达式

lambda表达式

语法规则

  1. 无参数,无返回值
    ()-> System.out.println("Hello Lambda!")
  2. 有一个参数,并且无返回值
    (x)-> System.out.println(x)
  3. 若只有一个参数,小括号可以省略不写
    x-> System.out.println(x)
  4. 有两个以上的参数,有返回值,并且 Lambda体中有多条语句
    Comparator<Integer> com =(x,y)->{ (System.out.print1n("函数式接口"); return Integer.compare(x,y); }
  5. 若 Lambda体中只有一条语句, return和大括号都可以省略不写
    Comparator<Integer> com =(x,y) -> Integer. compare (x,y)
  6. 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(消费型接口)Tvoid对类型为T的对象应用操作,void accept(T t)
Supplier 供给型接口T返回类型为T的对象,T get();
Function<T, R> 函数型接口TR对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t);
Predicate 断定型接口Tboolean类型为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


版权声明:本文为weixin_43988251原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。