当前位置:网站首页>Lambda表达式 | 浅解
Lambda表达式 | 浅解
2022-06-12 11:21:00 【蓝布棉】
Lambda表达式
简介
- Lambda表达式支持将代码块作为方法参数,允许使用更简洁的代码来创建只有一个抽象方法的接口(被称为函数式接口)的实例。
- 函数式接口:只含一个抽象方法的接口。
- Lambda表达式就相当于一个匿名方法。
- 作用:代替匿名内部类的繁琐语法。
- 部分:形参列表(允许省略形参类型,圆括号);箭头 -> ;代码块(可以省略花括号,return)
- Lambda表达式实际上会被当成一个任意类型的对象。
- Lambda表达式本质是一个函数。
(参数列表) -> {
方法体;
};
简单的Lambda表达式
- 用匿名内部类实现:
//函数式接口:只含一个抽象方法的接口
interface Cal{
int add(int a, int b);
}
//这个是我们以前的实现,匿名内部类,然后调用执行;
public class Program {
public static void main(String[] args) {
//匿名内部类
Cal c1 = new Cal() {
//重写实现接口
@Override
public int add(int a, int b) {
return a+b;
}
};
//调用执行
int c = c1.add(1, 2);
System.out.println(c);
}
}
- 用Lambda表达式改写下:
//函数式接口:只含一个抽象方法的接口
interface Cal{
int add(int a, int b);
}
//用Lambda表达式改写下:
public class Program {
public static void main(String[] args) {
//Lambda表达式
Cal c1=(int a,int b) ->{
return a+b;
};
//调用执行
int c=c1.add(1,2);
System.out.println(c);
}
}
Lambda表达式语法
- 搞一个案例,接口方法参数,无参,单个参数,两个参数,有返回值,没有返回值,这六种情况都罗列下:
public class Test {
public static void main(String[] args) {
I1 i1 = () -> {
System.out.println("无返回值、无参数");
};
i1.test();//无返回值、无参数
I2 i2 = (int a, int b) -> {
System.out.println("无返回值,多个参数。a=" + a + ", b=" + b);
};
i2.test(2, 3);//无返回值,多个参数。a=2, b=3
I3 i3 = () -> {
System.out.println("有返回值、无参数");
return 100;
};
System.out.println(i3.test());//有返回值、无参数 100
I4 i4 = (int a, int b) -> {
System.out.println("有返回值,多个参数。a=" + a + ",b=" + b);
return a + b;
};
System.out.println(i6.test(2, 4));//有返回值,多个参数。a=2,b=4 6
}
}
interface I1 {
//无返回值、无参数
void test();
}
interface I2 {
//无返回值,多个参数
void test(int a, int b);
}
interface I3 {
//有返回值、无参数
int test();
}
interface I4 {
//有返回值,多个参数
int test(int a, int b);
}
Lambda表达式精简语法
参数类型可以省略。
假如只有一个参数,()括号可以省略。
如果方法体只有一条语句,{}大括号可以省略。
如果方法体中唯一的语句是return返回语句,那省略大括号的同时return也可以省略。
//省略前的
I6 i6=(int a, int b)->{
return a+b;
};
// 省略:参数类型,{}大括号,return
I6 i6=(a,b)->a+b;
方法引用
- 有时候多个lambda表达式实现函数是一样的话,我们可以封装成通用方法,以便于维护;
- 这时候可以用方法引用实现:
语法是:对象::方法(需new一个对象)
若是static方法: 类名::方法(无需new一个对象,直接类名)
public class Program2 {
public static void main(String[] args) {
// 方法引用
// 普通方法 对象名::方法名 (需new一个对象)
Program2 program2 = new Program2();
I5 i5 = program2::test;
System.out.println(i5.test(1));
// static方法 类名::方法名 (无需new一个对象,直接类名)
I5 i52 = Program2::test2;
System.out.println(i52.test(1));
}
public int test(int a){
return a-2;
}
//static方法
public static int test2(int a){
return a-2;
}
}
interface I5{
//单个参数有返回值
int test(int a);
}
构造方法引用
- 如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用;
- 语法:类名::new
public class Program3 {
public static void main(String[] args) {
// 普通方式
DogService dogService = ()->{
return new Dog();
};
dogService.getDog();
// 简化方式
DogService dogService2 = ()->new Dog();
dogService2.getDog();
// 构造方法引用
DogService dogService3 = Dog::new;
dogService3.getDog();
// 构造方法引用 有参
DogService2 dogService21 = Dog::new;
dogService21.getDog("一二三",8);
}
}
//在定义两个接口:
interface DogService{
Dog getDog();
}
interface DogService2{
Dog getDog(String name,int age);
}
//先定义一个Dog实体,实现无参和有参构造方法
class Dog {
private String name;
private int age;
public Dog() {
System.out.println("无参构造方法");
}
public Dog(String name, int age) {
System.out.println("有参构造方法");
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Dog{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
@FunctionalInterface注解
- 这个注解是函数式接口注解,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。
- 接口有且仅有一个抽象方法
- 该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好地让编译器进行检查。如果编写的不是函数式接口,但是加上了@FunctionInterface,那么编译器会报错
系统内置函数式接口
- Java8的推出,是以Lambda重要特性,一起推出的,其中系统内置了一系列函数式接口。
- 再jdk的java.util.function包下,有一系列的内置函数式接口:比如常用的Consumer,Comparator,Predicate,Supplier等。
Lambda表达式与匿名内部类的联系和区别
- Lambda表达式是匿名内部类的一种简化。
- 相同点:(1)都可以直接访问“effectively final”的局部变量,以及外部类的成员变量;(2)都可以直接调用从接口中继承的默认方法。
- 区别:(1)匿名内部类可以为任何接口创建实例,Lambda表达式只能为函数式接口创建实例;(2)匿名内部类可以为抽象类甚至不同类创建实例;(3)匿名内部类允许调用接口中定义的默认方法。
使用Lambda表达式调用Arrays的类方法
- Arrays类的有些方法需要Comparator、XXXOperator、XXXFunction等接口的实例,都是函数式接口,因此可以使用Lambda表达式来调用Arrays的类方法。
本文为视频课程的学习笔记,加自己一点总结。
边栏推荐
- ^33 variable promotion and function promotion interview questions
- Common configuration commands for Cisco network device security management
- PHP get (remote) large file method record
- NLP data set download address for naturallanguageprocessing
- AcWing 128. 编辑器(对顶栈 实现序列内部指定位置高效修改)
- 架构训练模块 7
- 人脸识别pip 安装dlib库失败
- 自然语言处理nlp 数据集下载地址
- M-Arch(番外13)GD32L233评测-来点音乐
- MATLAB中stairs函数使用
猜你喜欢

Malicious code analysis practice - lab03-03 Exe basic dynamic analysis

无限生长,我们都将奔赴未来 | InfoQ中国成立15周年

mysql中的索引show index from XXX每个参数的意义

Using stairs function in MATLAB

Malicious code analysis practice - lab03-01 Exe basic dynamic analysis

MYSQL——内置函数

Redis summary

十折交叉验证代码中的问题

DS18B20数字温度计 (一) 电气特性, 寄生供电模式和远距离接线

This and final keywords
随机推荐
How the ArrayList collection implements ascending and descending order
Golang基础(6)
对网络库协程的思考——读brpc有感
疫情居家办公体验 | 社区征文
Using stairs function in MATLAB
自然语言处理nlp 数据集下载地址
Malicious code analysis practice - lab03-02 DLL analysis
LLD monitored by ZABBIX
k58.第一章 基于kubeadm安装kubernetes v1.23 -- 集群部署
LVS health state detection based on application layer
K59. Chapter 2 installing kubernetes V1.23 based on binary packages -- cluster deployment
Pytorch笔记
Index query efficiency of MySQL
你需要社交媒体二维码的21个理由
Redis summary
Clj3-100alh30 residual current relay
Building 64 bit wampserver and DVWA in win7 virtual machine
The difference between meta universe chain games and traditional games
arm各种交叉编译工具的区别
k53.第二章 基于二进制包安装kubernetes v1.22 --集群部署