1.Lambda 介绍
从 JDK 1.8 开始引入了 Lambda 表达式,Lambda 表达式是一个匿名函数,没有方法名称,但是却可以像方法一样被调用。Lambda 表达式可以通过 {} 来定义,可以带有零个、一个、或多个参数。
Lambda 表达式语法格式:
(parameter) -> {statement}
parameter 是传入 Lambda 表达式的参数, -> 是 Lambda 表达式的分隔符,statement 是 Lambda 表达式要执行的语句,{}中是要执行的代码块。
2. 函数式接口
函数式接口是 Lambda 表达式和方法引用的前提,因此想要了解 Lambda 表达式,首先要了解函数式接口。
函数式接口在 JDK 1.8版本以上有效,需要 @FunctionalInterface 注解,@FunctionalInterface 语法格式严格要求当前接口有且只能有一个尚未完成的,缺省属性为 public abstract 修饰方法。函数式接口一般用于方法的增强,直接作为方法的参数,实现插件式编程。
@FunctionalInterface
interface Test {
void test();
}
3. Lambda 表达式基本使用
在传统的函数调用中,我们需要定义函数名和参数,然后通过函数名来调用这个函数,但是在有些场景下,我们仅需要使用该函数一次,并且这个函数不是很复杂,定义一个函数名再进行调用的过程显得过于繁琐,此时我们可以使用Lamba 表达式来实现对该函数的调用。Lambda 表达式从本质上来讲,就是一个匿名函数,因此在写Lambda 表达式的时候,不需要关心方法名是什么。
基本格式
(参数临时变量) -> {执行任务代码块}
Lambda 表达式关注的是接口中方法的返回值和参数
3.1 无参数无返回值
接口
@FunctionalInterface
interface A {
void test();
}
方法
public static void testLambda(Aa) {
a.test();
}
Lambda 表达式实现
public static void main(String[] args) {
testLambda(() ->
System.out.println("无参数无返回值 Lambda");
);// Lambda 表达式有且只有一行代码时,可以省略大括号
}
3.2 有参数无返回值
接口
有参数无返回值中最经典的就是消费者接口,即 Consumer<T> ,泛型可以在使用过程中支持数据多样性,同时满足数据类型一致化要求。
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
方法
public static void testLambda(String str, Consumer<String>handle) {
handle.accept(str);
}
Lambda 表达式实现
public static void main(String[] args) {
testLambda("Lambda 表达式",s->
System.out.println(Arrays.toString(s.toCharArray()));
// 代码块中只有一行,可以省略大括号
// 小括号中有且只有一个参数时,可以省略小括号
}
3.3 无参数有返回值
// 接口
// 无参数有返回值的接口中最经典的是生产者接口
@FunctionalInterface
interface Supplier<T> {
T get();
}
// 方法
public static String testLambda(Supplier<String> s) {
return s.get();
}
// Lambda 表达式实现
public static void main(String[] args) {
String str = testLambda(() -> {
return "无参数有返回值 Lambda"
});
System.out.println(str);
// Lambda 优化
String str1 = testLambda(()-> "无参数有返回值 Lambda");
// 代码块中只有一行代码,可以省略大括号
// 只要 —> 之后是一个字符串数据,内容可以满足当前 Lambda 所需,可以省略 return,前提是 Lambda 只有一行代码
System.out.println(str1);
}
3.4 有参数有返回值
// 有参数有返回值中比较经典的有过滤器接口 Predicate<T>
@FunctionalInterface
interface Predicate<T> {
int compare(T o1, T o2);
}
// 方法
public tatic Person[] Filter(Person[] array,Predicate<Person> filter) {
Person[] temp = new Person[array.length];
int count = 0;
for (int i = 0; i < array.length; i++) {
if (filter.test(array[i])) {
temp[count++] = array[i];
}
}
return temp;
}
// Lambda 表达式
public static void main(String[] args) {
Person[] array = new Person[5];
for (int i = 0; i < array.length; i++) {
int age = (int) (Math.random() * 50);
array[i] = new Person(i + 1, "张三", age, false);
}
Person[] temp = filterPersonArrayUsingPredicate(array, p -> p.getAge() > 10);
for (Person person : temp) {
System.out.println(person);
}
}
4. Lambda 表达式优点
简化代码,Lambda 表达式提供了一种更为简洁的编码方式,可以将方法作为参数传递给另一个方法,从而简化代码
代码复用,Lambda 表达式消除了需要编写多个方法的需求,因此可以避免大量的代码复制和粘贴。
更好的性能,在某些情况下,使用Lambda 表达式可以提高代码的执行速度,因此他们可以使用并行流来并行处理数据。
简化错误处理,使用Lambda 表达式可以简化错误处理,因此可以帮助我们更容易地捕获和处理异常。