• Java-1130


    Lambda表达式

    1. 为什么使用lambda
      1. lambda是一个匿名函数,是一段可以传递的代码,也可以理解为函数参数。基本形式() -> {}

      2. 简化了很多无用的代码,例如:相比匿名内部类定义比较器

        		/**
             * 匿名内部类
             */
            @Test
            public void test1(){
        
                //  匿名内部类实现接口,匿名内部类的实例作为参数
                Comparator<Integer> com =  new Comparator<Integer>() {
                    @Override
                    public int compare(Integer o1, Integer o2) {
                        return Integer.compare(o1,o2);
                    }
                };
                TreeSet<Integer> ts = new TreeSet<>(com);
            }
        
            /**
             * lambda表达式
             */
            @Test
            public void test2(){
                Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
              	//	更简洁可以这样写
                TreeSet<Integer> ts = new TreeSet<>(Integer::compare);
            }
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
      3. 对于一些重复代码可以使用相应的设计模式进行优化,例如定义比较器接口然后进行分别实现,不过代码量也不小。

      4. 总之就是一个词,简洁。

    2. Lambda基本语法
      1. lambda操作符:"->"也叫箭头操作符。左右侧分别为不同内容:

        1. 左侧:参数列表
        2. 右侧:所需执行功能,lambda体
      2. lambda表达式默认实现接口中需要实现的方法,当存在多个需要实现的方法时,需要函数式接口的支持
      3. 局部内部类应用同级别的局部变量,在jdk1.7之前必须是final,在1.8可以不加final,但是默认也是final,使用的时候不可以修改。Lambda也是同理,可以使用同级别局部变量,但是也将其默认为final

      4. lambda就是一个语法糖,简化了使用

    3. Lambda语法变化形式
      1. 语法格式一:无参数无返回值: () -> { }

        				/**
                 * 匿名内部类
                 */
                Runnable r = new Runnable() {
                    @Override
                    public void run() {
                        System.out.println("hello lambda!");
                    }
                };
        
                /**
                 * lambda
                 */
                Runnable r1 = () -> System.out.println("hello Lambda");
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
      2. 语法格式二:一个参数,并且无返回值,若只有一个参数,小括号可以不写

        				Consumer<String> con = (x)->System.out.println(x);
                con.accept("hello lambda!");
        
        • 1
        • 2
      3. 语法格式三:两个以上参数,并且lambda体中有多条语句,且有返回值。如果只有一条语句,return和大括号都可以不写

        				Comparator<Integer> com = (x,y)->{
                    System.out.println("函数式接口");
                    return Integer.compare(x,y);
                };
        
        • 1
        • 2
        • 3
        • 4
      4. 语法格式四:Lambda表达式的参数列表的数据类型可以省略不写,因为JVM的编译器可以通过上下文推断出数据类型,这个过程我们称之为类型推断。也可以写类型,但是如果要写类型,那么所以参数的类型都要写上。

        1. 类型推断只是语法糖,但是类型的检查都会做的,编译会做,编译器也会做
    4. Lambda表达式需要函数式接口支持
      1. 函数式接口:接口中只有一个抽象方法的接口,我们称之为函数式接口。可以使用@FunctionalInterface修饰,该注解可以检查是否是函数式接口
    5. Lambda底层和匿名内部类的区别
      1. 先来看一道题:
        在这里插入图片描述

      这道题答案选:A、C

      1. A刚才说过了,可以访问,但是默认final
      2. B就是要说的,他和匿名内部类底层是不同的,如何不同一会说;本质是一个语法糖是没错的
      3. C该指令用到了,匿名内部类也用了这个指令,不过lambda还用了匿名内部类没有用到的InvokeDynamic指令。
      4. D第一次和后续是无差异的,lambda通常是无状态的
    6. Lambda底册原理
      1. 匿名内部类的缺陷:

        1. 每一个匿名内部类编译后会生成一个.class文件,通常以ClassName$1命名,每个类文件使用之前需要加载和验证,会影响性能
        2. 每个新的匿名类都会创建一个新的子类型,如果用了一百多个匿名类会对JVM性能造成影响
      2. InvokeDynamic指令:

  • 相关阅读:
    Centos7.9云计算CloudStack4.15 高级网络配置(3)
    MATLAB算法实战应用案例精讲-【图像处理】SLAM技术详解
    SpringCloud环境搭建及入门案例
    去中心化的速度:零知识证明的进步
    jQuery 常用函数解析
    远程登陆Ubuntu服务器anaconda的使用问题(多用户)
    活动预告:如何培养高质量应用型医学人才?
    java毕业设计校园社区系统mybatis+源码+调试部署+系统+数据库+lw
    使用无服务器功能的云计算成新趋势?无服务器功能的隐藏挑战
    Opencv 基本操作三 实现各个形态学处理并实现多图展示
  • 原文地址:https://blog.csdn.net/lannister_awalys_pay/article/details/128124395