Lambda表达式
1.函数式编程思想概述
在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿什么东西做什么事情”。相对而言,面向对象过分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法--强调做什么,而不是以什么形式做
面向对象的思想:
做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情
函数式编程思想:
只要获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
2.Lambda表达式的标准格式
由三部分组成:
一些参数
一个箭头
一段代码
格式:
(参数列表)-> {一些重写方法的代码}
解释说明格式:
():接口中抽象方法的参数列表,没有参数,就空着;有参数,就写出参数,多个参数,使用逗号分隔
-> :传递的意思,把参数传递给方法体
{} :重写接口的抽象方法的方法体
案例1:Lambda表达式无参数无返回值
需求:
* 给定一个厨子Cook接口,内含唯一的抽象方法makeFood,且无参数,无返回值
* 使用Lambda标准格式调用invokeCook方法,打印输出“吃饭啦”字样

package cn.yjg.day10.Lambda;
/**
* 需求:
* 给定一个厨子Cook接口,内含唯一的抽象方法makeFood,且无参数,无返回值
* 使用Lambda标准格式调用invokeCook方法,打印输出“吃饭啦”字样
*/
public class Demo01Cook {
public static void main(String[] args) {
// 调用invokeCook方法,参数是Cook接口,传递Cook接口的匿名内部类对象
invokeCook(new Cook() {
@Override
public void makeFood() {
System.out.println("吃饭啦");
}
});
// 使用Lambda表达式简化匿名内部类的书写
invokeCook(() -> {
System.out.println("吃饭啦");
});
}
// 定义一个方法,参数传递Cook接口,方法内部调用Cook接口中的方法makeFood
public static void invokeCook(Cook cook) {
cook.makeFood();
}
}
运行结果:

案例2:Lambda表达式有参数有返回值的
需求:
使用数组存储多个Person对象
对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
使用一般的方法
Person.java
package com.company.service.Lambda;
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
}
}
Demo01Arrays.java
package com.company.service.Lambda;
import java.util.Arrays;
import java.util.Comparator;
public class Demo01Arrays {
public static void main(String[] args) {
// 使用数组存储多个Person对象
Person[] arr = {
new Person("陈钰琪", 20),
new Person("古力娜扎", 22),
new Person("关之琳", 52),
};
// 对数组中的Person对象使用Arrays的sort方法通过年龄进行排序(前边-后边)
Arrays.sort(arr, new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o1.getAge()-o2.getAge();
}
});
// 遍历数组,使用增强for循环
for (Person person : arr) {
System.out.println(person);
}
}
}
结果:

使用Lambda,简化匿名内部类
package com.company.service.Lambda;
import java.util.Arrays;
public class Demo02Arrays {
public static void main(String[] args) {
// 使用数组存储多个Person对象
Person[] arr = {
new Person("陈钰琪", 20),
new Person("古力娜扎", 22),
new Person("关之琳", 52),
};
// 对数组中的Person对象使用Arrays的sort方法通过年龄进行排序(前边-后边)
Arrays.sort(arr, (Person o1, Person o2) -> {
return o1.getAge()-o2.getAge();
});
// 遍历数组,使用增强for循环
for (Person person : arr) {
System.out.println(person);
}
}
}
案例3:
需求:
给定一个计算器Calculator接口,内含抽象方法calc可以将两个int数字相加得到和值
使用Lambda的标准格式调用invokeCalc方法,完成120和130的相加计算
Calulator.java
package com.company.service.Lambda;
public interface Calculator {
// 定义一个计算两个int整数和的方法并返回结果
public abstract int calc(int a, int b);
}
一般的方法
package com.company.service.Lambda;
public class Demo02Calculator {
public static void main(String[] args) {
// 调用invokeCalc方法,方法的参数是一个接口,可以使用匿名内部类
invokeCalc(120, 130, new Calculator() {
@Override
public int calc(int a, int b) {
return a+b;
}
});
}
/**
* 定义一个方法,参数传递两个int类型的整数,
* 参数传递Calculator接口,
* 方法内部调用Calculator中的方法calc计算两个整数的和
*/
public static void invokeCalc(int a, int b, Calculator c) {
int sum = c.calc(a, b);
System.out.println(sum);
}
}
使用Lambda简化匿名内部类
package com.company.service.Lambda;
public class Demo03Calculator {
public static void main(String[] args) {
// 调用invokeCalc方法,方法的参数是一个接口,可以使用匿名内部类
invokeCalc(120, 130,(int a, int b) -> {
return a+b;
});
}
/**
* 定义一个方法,参数传递两个int类型的整数,
* 参数传递Calculator接口,
* 方法内部调用Calculator中的方法calc计算两个整数的和
*/
public static void invokeCalc(int a, int b, Calculator c) {
int sum = c.calc(a, b);
System.out.println(sum);
}
}
3.Lambda省略格式
可推导,那就可省略
Lambda强调的是“做什么”而不是“怎么做”,所以凡是可以根据上下文推导得知的信息,都可以省略,例如可以写成
invokeCalc(120, 130, (a, b) -> a+b);
可以省略的内容:
(1)(参数列表):括号中参数列表的数据类型,可以省略不写
(2)(参数列表):括号中的参数如果只有一个,那么类型和()都可以省略
(3){一些代码}:如果{}中的代码只有一行,无论是否有返回值,都可以省略{},return,分号
注意:要省略这三个{},return,分号,必须要一起省略,
体现可推导可省略的例子

4.Lambda使用前提
1.使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。
无论是JDK内置的Runnable,Comparator接口还是自定义的接口,只有当接口的抽象方法存在唯一时,才可以使用Lambda
2.使用Lambda必须具有上下文推断
也就是方法的参数或局部变量的类型必须是Lambda对应的接口类型,才能使用Lambda作为该接口的实例
备注:
有且仅有一个抽象方法的接口,称为函数式接口

浙公网安备 33010602011771号