jdk8新特性之Lambda

Lambda体验
Lambda是一个匿名函数,可以理解为一段可以传递的代码。
Lambda表达式写法,代码如下:
借助Java 8的全新语法,上述 Runnable 接口的匿名内部类写法可以通过更简单的Lambda表达式达到相同的效果

 /**
     * 从匿名类到Lambda表达式的转变
     */
    @Test public void testLambdaHelloWorld() {
        // 匿名类01
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("Hello");
            }
        }).start();

        // lambda01
        new Thread(() -> System.out.println("Hello")).start();
    }

这段代码和刚才的执行效果是完全一样的,可以在JDK 8或更高的编译级别下通过。从代码的语义中可以看出:我们启动了一个线程,而线程任务的内容以一种更加简洁的形式被指定。我们只需要将要执行的代码放到一个Lambda表达式中,不需要定义类,不需要创建对象。
Lambda的优点:简化匿名内部类的使用,语法更加简单。

Lambda的标准格式
Lambda省去面向对象的条条框框,Lambda的标准格式格式由3个部分组成:

(参数类型 参数名称) -> {
       代码体;
}

无参数无返回值的Lambda

    @Test
    public void test(){
        goSwimming(new Swimmable(){
            @Override
            public void swimming() {
                System.out.println("我要游泳");
            }
        });
        goSwimming( () -> {
            System.out.println("我要游泳");
        });

    }

    // 练习无参数无返回值的Lambda
    public static void goSwimming(Swimmable s) {
        s.swimming();
    }
/**
 * @author WGR
 * @create 2020/3/23 -- 23:29
 */
public interface Swimmable {
    public abstract void swimming();
}

有参数有返回值的Lambda

    @Test
    public void test1(){
        goEatting( name ->{
            System.out.println("吃"+name);
            return 0 ;
        });
    }

    public static Integer goEatting(Eatable e){
        return e.eatting("饭");
    }
/**
 * @author WGR
 * @create 2020/3/23 -- 23:29
 */
public interface Swimmable {
    public abstract void swimming();
}
   @Test
    public void test3(){
        ArrayList<Person> persons = new ArrayList<>();
        persons.add(new Person("刘德华", 58, 174));
        persons.add(new Person("张学友", 58, 176));
        persons.add(new Person("刘德华", 54, 171));
        persons.add(new Person("黎明", 53, 178));

        Collections.sort(persons, (o1, o2) -> {
            return o2.getAge() - o1.getAge(); // 降序
        });

        persons.forEach((t) -> {
            System.out.println(t);
       

Lambda的实现原理
匿名内部类的class文件

 Lambda表达式的断点

关于这个方法 lambda$test$1 的命名:以lambda开头,因为是在test()函数里使用了lambda表达式,所以带有$test表示,因为是第二个,所以$01
如何调用这个方法呢?其实Lambda在运行的时候会生成一个内部类,为了验证是否生成内部类,可以在运行时加
上 -Djdk.internal.lambda.dumpProxyClasses ,加上这个参数后,运行时会将生成的内部类class码输出到一个文
件中。使用java命令如下:

java -Djdk.internal.lambda.dumpProxyClasses 要运行的包名.类名

小结 :

匿名内部类在编译的时候会一个class文件
Lambda在程序运行的时候形成一个类
1. 在类中新增一个方法,这个方法的方法体就是Lambda表达式中的代码
2. 还会形成一个匿名内部类,实现接口,重写抽象方法
3. 在接口的重写方法中会调用新生成的方法.

Lambda省略格式

 /**
     * lambda语法: 能省则省
     */
    @SuppressWarnings("unused")
    @Test public void testLambdaSyntax() {
        // 语法
        BinaryOperator<Integer> bo = (Integer x, Integer y) -> {
            return x+y;
        };

        // 简化1: 由于类型推断(编译器javac根据上下文环境推断出类型), 可以省略参数的类型
        bo = (x,y) -> {
            return x+y;
        };

        // 简化2: 当Lambda体只有一条语句的时候可以省略return和大括号{}
        bo = (x,y) -> x + y;

        // 简化3: 当参数只有一个时, 可以省略小括号
        Consumer<String> fun = args -> System.out.println(args);

        // 简化4: 当参数个数为零时, 使用()即可
        Runnable r1 = () -> System.out.println("Hello Lambda");

        // 简化5: 方法引用(下个新特性)
        Consumer<String> fun02 = System.out::println;
    }

Lambda的前提条件
Lambda的语法非常简洁,但是Lambda表达式不是随便使用的,使用时有几个条件要特别注意:
1. 方法的参数或局部变量类型必须为接口才能使用Lambda
2. 接口中有且仅有一个抽象方法

/**
 * @author WGR
 * @create 2020/3/24 -- 0:11
 */
public class LambdaCondition {
    public static void main(String[] args) {
        // 方法的参数或局部变量类型必须为接口才能使用Lambda
        test(() -> {
        });

        Flyable f = () -> {
            System.out.println("我会飞啦");
        };
    }

    public static void test(Flyable a) {
        new Person() {

        };
    }

}

// 只有一个抽象方法的接口称为函数式接口,我们就能使用Lambda
@FunctionalInterface // 检测这个接口是不是只有一个抽象方法
interface Flyable {
    // 接口中有且仅有一个抽象方法
    public abstract void eat();
    // public abstract void eat2();
}

原文地址:https://www.cnblogs.com/dalianpai/p/12556322.html

时间: 2024-07-30 10:28:43

jdk8新特性之Lambda的相关文章

jdk8新特性之lambda expressions

本文分两部分: 语法简单说明 lambda的使用 注:这两部分内容均以类+注释的方式进行说明,并且内容均来自官方教程(https://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html). 第一部分: /** * 语法说明类 * * lambda表达式包含下面几个要素: * 1.逗号分隔的参数列表,如CheckPerson.test(Person p),其中p表示一个Person的对象实例 * 2.向右箭头 →,

JDK8新特性02 Lambda表达式02_Lambda语法规则

//函数式接口:只有一个抽象方法的接口称为函数式接口. 可以使用注解 @FunctionalInterface 修饰 @FunctionalInterface public interface MyFun { public Integer getValue(Integer num); } import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.List;

JDK8新特性01 Lambda表达式01_设计的由来

1.java bean public class Employee { private int id; private String name; private int age; private double salary; public Employee() { } public Employee(String name) { this.name = name; } public Employee(String name, int age) { this.name = name; this.a

jdk8新特性--使用lambda表达式的延迟执行特性优化性能

使用lambda表达式的延迟加载特性对代码进行优化: 原文地址:https://www.cnblogs.com/niwotaxuexiba/p/10850339.html

一次电话Java面试的问题总结(JDK8新特性、哈希冲突、HashMap原理、线程安全、Linux查询命令、Hadoop节点)

面试涉及问题含有: Java JDK8新特性 集合(哈希冲突.HashMap的原理.自动排序的集合TreeSet) 多线程安全问题 String和StringBuffer JVM 原理.运行流程.内部结构 Linux 查询含有某字符串内容的命令grep 查询进程.GC状态.杀死进程 Hadoop五种节点介绍 -----------------------------------------------------------------------------------------------

JDK8 新特性

JDK8 新特性目录导航: Lambda 表达式 函数式接口 方法引用.构造器引用和数组引用 接口支持默认方法和静态方法 Stream API 增强类型推断 新的日期时间 API Optional 类 重复注解和类型注解 Lambda 表达式 Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递).可以写出更简洁.更灵活的代码.作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升. 如下示例,将一个匿名类转换为Lambda表达

C++11新特性:Lambda函数(匿名函数)

声明:本文参考了Alex Allain的文章http://www.cprogramming.com/c++11/c++11-lambda-closures.html 加入了自己的理解,不是简单的翻译 C++11终于知道要在语言中加入匿名函数了.匿名函数在很多时候可以为编码提供便利,这在下文会提到.很多语言中的匿名函数,如C++,都是用Lambda表达式实现的.Lambda表达式又称为lambda函数.我在下文中称之为Lambda函数. 为了明白Lambda函数的用处,请务必先搞明白C++中的自动

C++11 新特性之 Lambda表达式

lambda表达式可以用于创建并定义匿名的函数对象,以简化编程工作 Lambda的语法如下: [函数对象参数](操作符重载函数参数)->返回值类型{函数体} []内的参数指的是Lambda表达式可以取得的变量.(2)函数中的param就是指函数可以得到在Lambda表达式外的全局变量, 如果在[]中传入=的话,即是可以取得所有的外部变量,如(1)和(3)Lambda表达式 ()内的参数是每次调用函数时传入的参数. ->后加上的是Lambda表达式返回值的类型,如(3)中返回了一个int类型的变

java进阶一之jdk8新特性

1.官方发布的jdk8新特性 2.51CTO相关专题