java学习日记 Lambda表达式

    技术2026-01-13  9

    JAVA Lambda表达式

    Lambda表达式冗余的Runnable代码函数式编程面对对象的思想函数式编程的思想 代码实现代码分析 编程思想的转换做什么,而不是怎么做 Lambda的更优写法代码 语义分析标准格式无参数无返回值代码练习有参数有返回值代码练习 Lambda省略省略规则省略练习

    Lambda表达式

    冗余的Runnable代码

    函数式编程

    面对对象的思想

    做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成这个事情

    函数式编程的思想

    只要获取到结果,谁去做的,怎么做的都不重要,重视结果不重视过程。

    代码实现

    package project; /* * 使用Runnable接口的方式实现多线程程序 */ public class test{ public static void main(String[] args) { //创建Runnable接口的实现类对象 test01 t1=new test01(); //创建thread对象 构造方法中传递Runnable接口的实现类 Thread t=new Thread(t1); //调用start方法开启新线程 执行run方法 t.start(); //简化代码 使用匿名内部类 实现多线程程序 Runnable r=new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+"新的线程创建了"); } }; new Thread(r).start(); //再简化代码 new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName()+"新的线程创建了"); } }).start(); } }

    test01类:

    package project; /* *创建Runnable接口的实现类 重写run方法,设置线程任务 */ public class test01 implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"新的线程创建了"); } }

    代码分析

    对于Runnable的匿名内部类用法 可以分析出

    Thread类需要Runnable接口作为参数,其中的抽象方法run是用来指定线程任务内容的核心为了指定run的方法体 不得不需要Runnable接口的实现类为了省区定义一个Runnable实现类的麻烦 不得不使用匿名内部类必须覆盖重写抽象run方法 所以方法名称 方法参数 方法返回值不得不再写一遍 并且不能写错实际上 似乎只有方法体才是关键所在

    编程思想的转换

    做什么,而不是怎么做

    我们不是真的想创建一个匿名内部类对象,我们只是为了做这件事情而不得不创建一个对象。我们真正希望做的事情是:将run方法体内的代码传递给Thread类知道

    传递一段代码 这才是我们真正的目的 而创建对象只是限于面对对象语法而不得不采用的一种手段

    如果将怎么做回归到做什么的本质上 就会发现只要能够更好的达到目的 过程和形式并不重要

    Lambda的更优写法

    代码

    使用Lambda表达式实现上述Runnable匿名内部类的效果

    package project; /* * 使用Lambda表达式来实现优化 */ public class test{ public static void main(String[] args) { new Thread(()->System.out.println("多线程任务执行")).start();//启动线程 } }

    。。。确实有点简单哦

    语义分析

    Runnable接口只有一个run方法的定义:

    public void run(); 即制定了一种做事情的方案(一个函数):无参数:不需要任何条件就可以执行该方案无返回值:该方案不产生任何结果代码块(方法体):该方案的具体执行步骤

    同样的予以体现在Lambda语法中 要更加简单

    ()->System.out.println("多线程任务执行")

    前面的一对小括号就是run方法的参数(无) 代表不需要任何田间中间的一个箭头代表将前面的参数传递给后面的代码后面的输出语句就是业务逻辑代码

    标准格式

    一些参数一个箭头一段代码

    Lambda标准格式为 (参数类型 参数名称)->{ 代码语句 }

    格式说明:

    小括号内的语法与传统方法参数列表一致:无参数留空; 多个参数则用逗号分隔->是新引入的语法形式, 代表指向动作大括号内的语法与传统方法体要求基本一致(需要执行的代码)

    无参数无返回值代码练习

    Cook接口:

    package project; public interface Cook { void makeFood(); }

    main:

    package project; /* * Lambda标准格式 * 由三部分组成 * a 一些参数 * b 一个箭头 * c 一段代码 * 格式: * (参数类型 参数名称)->{ 代码语句 } * 解释说明格式: * 小括号内的语法与传统方法参数列表一致:无参数留空; 多个参数则用逗号分隔 * ```->```是新引入的语法形式, 代表指向动作 * 大括号内的语法与传统方法体要求基本一致(需要执行的代码) * * 需求: * 给定一个Cook厨子接口 内含唯一的抽象方法makeFood 且无参数 无返回值 * 使用Lambda表达式调用invokeCook方法 打印输出“吃饭了!”字样 */ public class test{ public static void main(String[] args) { //使用Lambda表达式调用invokeCook方法 //匿名内部类 invokeCook(new Cook() { @Override public void makeFood() { System.out.println("吃饭了!"); } }); //使用Lambda表达式 invokeCook(()-> { System.out.println("吃饭了!"); } ); } //定义了一个方法 参数传递了Cook接口 方法内部调用Cook接口中的方法makeFood private static void invokeCook(Cook cook) { cook.makeFood(); } }

    有参数有返回值代码练习

    Person类:

    package project; public class Person { private String name; private int age; public Person() { // TODO Auto-generated constructor stub } public Person(String name,int age){ this.age = age; this.name = name; } @Override public String toString() { // TODO Auto-generated method stub return "Person{"+ "name='"+name+'\''+ ",age="+age+ '}'; } public String getName() { return name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void setName(String name) { this.name = name; } }

    匿名内部类和Lambda表达式的对比

    package project; /* * Lambda表达式有参数有返回值的练习 * 需求: * 使用数组存储多个Person对象 * 对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序 */ import java.util.Arrays; import java.util.Comparator; public class test{ public static void main(String[] args) { //使用数组存储多个Person对象 Person[] arr= { new Person("刘艳",18), new Person("张三",25), new Person("赵四",20), }; //对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序 // Arrays.sort(arr,new Comparator<Person>() { // // @Override // public int compare(Person o1, Person o2) { // // return o1.getAge()-o2.getAge(); // } // }); //使用Lambda表达式 简化匿名内部类 Arrays.sort(arr,(Person o1,Person o2)->{ return o1.getAge()-o2.getAge(); }); //遍历数组 for(Person p:arr) { System.out.println(p); } } }

    Lambda省略

    省略规则

    在Lambda标准格式的基础上,使用省略写法的规则为:

    小括号内参数的类型可以省略;如果小括号内有且仅有一个参,则小括号可以省略;如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。

    省略练习

    非省略形式

    Arrays.sort(arr,(Person o1,Person o2)->{ return o1.getAge()-o2.getAge(); });

    省略形式

    Arrays.sort(arr,(o1,o2)->o1.getAge()-o2.getAge());
    Processed: 0.012, SQL: 9