Lambda表达式的详细解析

目录

前言

一、lambda是什么?

二、使用lambda表达式

1.函数式接口

2.lambda的例子

1.抽象方法无参数无返回值

2.抽象方法带参无返回值

3.带参数带返回值

三.lambda表达式的简化

四.lambda表达式的实现原理

总结


前言

lambda表达式是Java8最受期待的新特性。接下来将从lambda表达式的作用,语法,原理,优缺点,以及一些demo来分析lambda表达式。

一、lambda是什么?

lambda表达式也叫闭包,lambda允许把函数作为参数传递到方法(把代码段作为方法的参数传递到方法中)。

用途:用于简化Java接口式的匿名内部类,集合的迭代,Stream操作,与函数式接口Predicate配合等等。文章主要介绍用于简化Java接口式的匿名内部类。

优点:1代码简洁 2. 不会生成class文件   

缺点:降低了可读性

二、使用lambda表达式

1.函数式接口

函数式接口概念:只有一个抽象方法的接口。tip:不包含object中的方法,如toString()

//这个就是一个函数式接口
public interface Eatable {
    public void eat();
}

2.lambda的例子

基本语法:(参数1,参数2,......)->{.....}

1.抽象方法无参数无返回值

接口

public interface People {
    public void Runable();
}
  • 定义一个测试类Lambdaclass,在测试类中提供两个方法
    ①、一个方法是:usePeople(People p)
    ②、一个方法是主方法,在主方法中调用usePeople方法

(1) 通过实现类的方法

//people实现类
public class PeopleImpl implements People{
    @Override
    public void Runable() {
        System.out.println("我在跑步");
    }
}
................
public class LambdaClass {
    public static void main(String[] args) {

         //普通
        People people = new PeopleImpl();
        usePeople(people);


}

 private static void usePeople(People p){
        p.Runable();
    }

}

(2)匿名内部类

public class LambdaClass {
    public static void main(String[] args) {

      //匿名内部类
        usePeople(new People() {
            @Override
            public void Runable() {
                System.out.println("我在跑步1");
            }
        });

}

 private static void usePeople(People p){
        p.Runable();
    }

}

(3)lambda表达式

public class LambdaClass {
    public static void main(String[] args) {

        //lambda表达式
        usePeople(()->System.out.println("我在跑步2"));
}

 private static void usePeople(People p){
        p.Runable();
    }

}

通过观察上面的实现方法比较,是不是lambda表达式的非常简洁呢?原来需要一个peopleimpl的一个实现类,使用lambda表达式只需要一个表达式就行了。

2.抽象方法带参无返回值

接口

public interface People {
    public void Runable(String s);
}

还是和上面的一样

public class LambdaClass {
    public static void main(String[] args) {

           //lambda表达式
        usePeople((String s)->{
            System.out.println("我在跑步2");
            System.out.println(s);

        });

 private static void usePeople(People p){
        p.Runable("aa");
    }

}

3.带参数带返回值

public interface People {
    public String Runable(String s);
}
public class LambdaClass {
    public static void main(String[] args) {

         //lambda表达式
        usePeople((String s)->{
            System.out.println("我在跑步2");
            System.out.println(s);
            return s;

        });

 private static void usePeople(People p){
        p.Runable("aa");
    }

}

三.lambda表达式的简化

lambda表达式的基础用法和语法以及讲解完了,那它还有什么简化呢?当然有那就是----------方法的引用   

格式:类名::方法名 或 对象名::方法名

还是以上面的demo为基础

public class LambdaClass {
    public static void main(String[] args) {

    
        //lambda表达式
        usePeople((String s)->System.out.println(s));
        //方法的引用
        usePeople(System.out::println);

 private static void usePeople(People p){
        p.Runable("aa");
    }

}

上面的

(String s)->System.out.println(s)和System.out::println   是一样的只是对lambda表达式进行了简化 

再来看一个引用的例子:  相信有了这个例子之后,会对方法的引用理解的更加好


@FunctionalInterface
public interface Consumer<T> {
    void accept(T var1);

    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (t) -> {
            this.accept(t);
            after.accept(t);
        };
    }
}




public class LambdaClass {
    public static void main(String[] args) {



    Consumer<String> con = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        con.accept("3333");

        Consumer<String> con1 = s->System.out.println(s);
        con1.accept("aaaa");

        Consumer<String> con2 = System.out::println;
        con2.accept("bbb");




}

四.lambda表达式的实现原理

public class InterfaceDemo {
    //定义函数接口方法
    public void hi(MyInterface myInterface){
        myInterface.sayHi();
    }
    public static void main(String[] args) {
        InterfaceDemo demo = new InterfaceDemo();
        demo.hi(()-> System.out.println("我是lambda"));
    }

编译之后

public class InterfaceDemo {
    //定义函数接口方法
    public void hi(MyInterface myInterface){
        myInterface.sayHi();
    }
    
    //编译器自动添加静态方法,方便动态生成的内部类调用
    private static void lambda$main$0(){
        System.out.println("我是lambda");
    }
 
    public static void main(String[] args) {
        
        //编译器动态创建的局部内部类
        final class InterfaceDemo$$Lambda$14 implements MyInterface {
            private InterfaceDemo$$Lambda$14() {
            }
            @LambdaForm.Hidden
            public void sayHi() {
                InterfaceDemo.lambda$main$0();
            }
        }
        
        InterfaceDemo demo = new InterfaceDemo();
        demo.hi(new InterfaceDemo$$Lambda$14());
    }

由上面可知   

1.jdk编译时使用时会给使用lambda表达式的类,添加一个私有,静态方法,格式:lambda$方法名$序号

2.动态创建一个局部内部类,该类实现了函数接口,重写函数接口唯一的抽象方法,局部内部类重写接口抽象方法

lambda表达式实际上是:   常规的接口实现,只是简化了代码。


总结

主要讲了lambda表达式的概念,基本语法和运用,以及方法引用,还有一些其它的用法和细节就不再赘述了。

有错误的地方欢迎指出

参考文章:

https://blog.csdn.net/jiankunking/article/details/79825928?

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值