简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!
优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀
优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀
人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.
1.前言
本篇目的:Java基础之lambda表达式
2.java lambda表达式介绍
-
Java的Lambda表达式是Java 8引入的一种新特性,允许我们以更简洁的方式表示匿名函数。Lambda表达式可以看作是一种简洁的、函数式编程风格的代码块。
-
Lambda表达式的基本语法如下:
(parameter-list) -> { function-body }
parameter-list:表示输入参数列表
->:表示Lambda运算符
function-body:表示是Lambda函数体。
以下是一些Lambda表达式的例子:
1.无参数Lambda表达式:
() -> { System.out.println("Hello, World!"); }
2.单个参数的Lambda表达式(参数类型可以省略):
x -> { System.out.println(x); }
3.多个参数的Lambda表达式:
(x, y) -> { System.out.println(x + y); }
4.当Lambda函数体只有一条语句时,可以省略大括号和return关键字:
(x, y) -> x + y
Lambda表达式通常与函数式接口一起使用,例如Java的Runnable,Comparator等接口。从Java 8开始,接口可以有默认方法和静态方法,这使得接口可以包含实现,从而可以像类一样使用。如果一个接口只有一个抽象方法,那么这个接口就是一个函数式接口。
例如,使用Lambda表达式和函数式接口Comparator进行排序:
List<Integer> numbers = Arrays.asList(3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5); Collections.sort(numbers, (a, b) -> a - b); System.out.println(numbers);
在这个例子中,(a, b) -> a - b就是一个Lambda表达式,它实现了Comparator接口的compare方法,用于比较两个整数的大小。
3.Java Lambda 表达式
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
Lambda 表达式语法
lambda 表达式的语法格式如下:
方式一:
(parameters) -> expression方式二:
(parameters) ->{ statements; }
**
parameters:表示参数列表。
expression 或 { statements; } :表示Lambda 表达式的主体。
如果只有一个参数,可以省略括号;
如果没有参数,也需要空括号。
**
Lambda 表达式的简单例子:1. 不需要参数,返回值为3
() -> 3 2. 接收一个参数,返回其3倍的值
x -> 3 * x 3. 接受2个参数,并返回他们的差值
(x, y) -> x – y 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y 5. 接受一个String 对象,并打印,不返回任何值
(String s) -> System.out.print(s)
4.lambda表达式代码实例
v1.0
public class Test {public static void main(String args[]){SAY say = message -> System.out.println("Hello " + message);say.print("Friends.");}interface SAY {void print(String message);}
}
注释:
message 是一个字符串(String)类型的参数。它是SAY接口中print方法的参数。
代码中的 message -> System.out.println("Hello " + message); 是一个Lambda表达式,它创建了一个实现了SAY接口的匿名类实例。
这个Lambda表达式实现了print方法,当调用print方法并传入一个字符串参数时,它会打印出"Hello ",后跟传入的字符串参数。具体来说,message -> System.out.println("Hello " + message); 这个Lambda表达式的意思是:
message 是这个Lambda表达式的参数,它的类型由print方法的定义决定,即String类型。
System.out.println("Hello " + message); 是这个Lambda表达式的主体,它实现了print方法的功能,即打印出"Hello "后跟message的值。
v2.0
Lambda表达式的固定语法:
(parameter-list) -> { function-body }
public class Test1 {interface SAY {void print(int mess);}interface ADD {void add(int a, int b);}public static void main(String args[]){//v1.0//SAY say = (message) -> System.out.println("Hello " + message);SAY say = (message) -> {System.out.println("Hello " + message);};say.print(1234);//v2.0//ADD at = (a, b) -> System.out.println("a = " + a + " b = " +b);ADD at = (a, b) -> {System.out.println("a = " + a + " b = " + b);};at.add(12,34);}
}
(message):表示参数.
->: 表示Lambda运算符.
{System.out.println("Hello " + message);};:表示函数体.
say:表示SAY类的对象.
ADD接口和lambda表达式本质解释:
ADD at = (a, b) -> {System.out.println("a = " + a + " b = " + b);}; 是一个赋值语句。这行代码做了以下几件事:
定义了一个名为 at 的变量,它的类型是 ADD。
ADD 是一个函数式接口,它有一个抽象方法 add(int a, int b)。
使用 Lambda 表达式 (a, b) -> {System.out.println("a = " + a + " b = " + b);} 来创建 ADD 接口的一个实例。
这个 Lambda 表达式实现了 ADD 接口的 add 方法。(a, b) 是参数列表,表示 add 方法接受两个整数参数。
-> 是 Lambda 运算符,它分隔了参数列表和 Lambda 函数体。
{System.out.println("a = " + a + " b = " + b);} 是 Lambda 函数体,它包含了要执行的代码。
在这个例子中,代码是打印参数 a 和 b 的值。
最后,这个 Lambda 表达式创建的 ADD 接口实例被赋值给变量 at。因此,ADD at = (a, b) -> {System.out.println("a = " + a + " b = " + b);}; 是一行赋值语句,
它创建了一个 ADD 类型的对象(实际上是一个 Lambda 表达式),并将其赋值给变量 at。
之后,你可以通过调用 at.add(12, 34); 来执行这个 Lambda 表达式,它会打印出 a = 12 b = 34。
问题:既然是(a, b) -> {System.out.println("a = " + a + " b = " + b);};实现了接口类ADD的方法add,那么为什么可以将(a, b) -> {System.out.println("a = " + a + " b = " + b);};赋值给at对象,而不是add方法呢?
你是在创建一个ADD类型的对象(即一个函数式接口的实例),并将这个Lambda表达式(实现了add方法的实例)赋值给变量at。
这里,at是一个函数式接口的引用,而不是一个方法的引用。在Java中,方法的调用是通过对象(或类的静态上下文)来完成的。
因此,当你调用at.add(12, 34);时,你实际上是在通过at这个对象(即函数式接口的实例)来调用add方法,
而这个方法是由Lambda表达式提供的实现。简而言之,(a, b) -> {System.out.println("a = " + a + " b = " + b);}这个Lambda表达式创建了一个匿名类,
这个匿名类实现了ADD接口,并重写了add方法。然后,这个匿名类的实例被赋值给了at变量。
当你调用at.add(12, 34);时,你实际上是在调用这个匿名类实例的add方法。
v3.0
emacs SimpleLambdaExample.java
public class SimpleLambdaExample {public static void main(String[] args) {// Lambda 表达式:带有参数和返回值Calculator addOperation = (a, b) -> a + b;// 调用 Lambda 表达式int result = addOperation.calculate(5, 3);// 打印结果System.out.println("Result: " + result);}// 函数式接口定义@FunctionalInterfaceinterface Calculator {int calculate(int a, int b);}
}
编译:
javac SimpleLambdaExample.java
javac SimpleLambdaExample
v4.0
// CarServiceProviderExample.java// 导入必要的类
import java.util.ArrayList;
import java.util.List;// 定义 Car 类
class Car {private String model;// Car 类的构造方法public Car(String model) {this.model = model;}// 获取汽车型号的方法public String getModel() {return model;}
}// 定义 CarServiceProvider 类
class CarServiceProvider {// 存储 CarListener 实例的列表private List<CarListener> listeners = new ArrayList<>();// 添加 CarListener 到列表的方法public void addListener(CarListener listener) {listeners.add(listener);}// 通知所有监听器有关 Car 对象的方法public void notifyListeners(Car car) {// 遍历监听器列表,并为每个调用 onCarEvent 方法for (CarListener listener : listeners) {listener.onCarEvent(car);}}
}// 定义 CarListener 的函数式接口
@FunctionalInterface
interface CarListener {// 监听器必须实现的抽象方法void onCarEvent(Car car);
}// 主例程
public class CarServiceProviderExample {public static void main(String[] args) {// 创建 CarServiceProvider 实例CarServiceProvider carServiceProvider = new CarServiceProvider();// 使用 lambda 表达式添加一个 CarListenercarServiceProvider.addListener(car -> {// 当接收到事件时打印消息System.out.println("收到汽车型号:" + car.getModel());});// 创建一个模拟的 Car 对象,型号为 "特斯拉"Car simulatedCar = new Car("特斯拉");// 通知监听器有关模拟汽车事件carServiceProvider.notifyListeners(simulatedCar);}
}
编译:
javac CarServiceProviderExample.java
javac CarServiceProviderExample