在实际开发过程中和Spring框架中随处可见Lambda表达式,如果对Lambda表达式还不清楚,那在阅读代码时候都不知道具体啥意思。最近自己也是对这部分做了总结,分享出来和大家一起交流讨论!
1.Lambda是什么
一句话总结:用简洁的方式来实现只有一个抽象方法的接口。
Lambda表达式是一种可以用来创建匿名函数的语法,可以将Lambda表达式视为一种简化版的方法定义。它提供了一种更简洁的方式来实现只有一个抽象方法的接口,这个接口被称为函数式接口,将一个方法体封装到一个对象中,使得我们可以像使用普通对象一样使用它。
Lambda表达式的语法如下:
(parameters) -> expression
或者:
(parameters) -> { statements; }
其中,parameters是参数列表,可以为空;expression是单个表达式,用来返回Lambda表达式的结果;statements是一组语句,用来执行Lambda表达式的操作。
2.为什么要有Lambda
Lambda表达式的引入主要是为了实现函数式编程,它可以使得Java程序更加简洁、易读、易维护。在Java 8之前,Java程序主要是面向对象编程,这意味着Java程序是由一系列类组成的,这些类通常包含一些方法,而方法则是由一组语句构成的。在Java 8之后,Java引入了Lambda表达式,它可以让Java程序更加灵活地实现函数式编程,从而提高代码的可读性和可维护性。
使用Lambda表达式可以让我们更加关注程序的逻辑,而不是方法的实现细节。Lambda表达式的使用可以简化代码,减少代码的冗余,同时也提高了代码的可读性和可维护性。
3.使用场景
Lambda表达式主要用于函数式接口和Stream API中。下面我们将从这两个方面介绍Lambda表达式的使用。
3.1 函数式接口中的Lambda表达式
函数式接口是指只有一个抽象方法的接口,例如:
@FunctionalInterface
interface Converter<F, T> {
T convert(F from);
}
在Java 8之前,实现这样的接口需要定义一个具体的类,并实现接口中的方法。在Java 8中,我们可以使用Lambda表达式来实现这样的接口。例如:
Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
Integer converted = converter.convert("123");
System.out.println(converted); // 输出:123
在上面的代码中,我们使用Lambda表达式实现了Converter接口,并将一个字符串转换为整数。在Lambda表达式中,我们将字符串作为参数传递给Lambda表达式,Lambda表达式中的代码将字符串转换为整数并返回。
Lambda表达式的参数可以推断出类型,因此在上面的代码中,我们可以省略参数类型的声明。如果Lambda表达式中只有一个参数,则可以省略参数列表的括号。例如:
Converter<String, Integer> converter = from -> Integer.valueOf(from);
Lambda表达式中的语句可以是任意的代码块,也可以是单个表达式。例如:
Converter<String, Integer> converter = from -> {
if (from == null) {
return null;
}
return Integer.valueOf(from);
};
3.2 Stream API中的Lambda表达式
Java 8中引入了Stream API,它提供了一种方便的方式来处理集合数据。Stream API中大量使用了Lambda表达式,下面是一些使用Lambda表达式的例子:
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream().filter(n -> n % 2 == 0).mapToInt(Integer::intValue).sum();
System.out.println(sum); // 输出:6
在上面的代码中,我们使用Lambda表达式过滤出所有偶数,并将它们转换为int类型的数字,并对它们求和。在Lambda表达式中,我们使用了filter方法和mapToInt方法来处理集合数据。
Lambda表达式还可以用于排序,例如:
List<String> names = Arrays.asList("John", "Mary", "Alice");
names.sort((a, b) -> a.compareTo(b));
System.out.println(names); // 输出:[Alice, John, Mary]
在上面的代码中,我们使用Lambda表达式对字符串进行排序。在Lambda表达式中,我们使用了compareTo方法来比较字符串的大小关系。
4.Lambda表达式写法
Lambda表达式是一个匿名函数,它可以像变量一样传递和使用。Lambda表达式的语法非常简洁,可以使用多种不同的写法来表示同一个Lambda表达式。
1. 无参数Lambda表达式
() -> { System.out.println("Hello, world!"); }
这是最简单的Lambda表达式,它没有参数,只包含一个代码块。在代码块中,我们可以执行任何需要执行的代码。
2. 带参数Lambda表达式
(x) -> { System.out.println("Hello, " + x); }
这个Lambda表达式包含一个参数x,我们可以在代码块中使用这个参数执行一些操作。
3. 带多个参数的Lambda表达式
(x, y) -> { System.out.println("Hello, " + x + " and " + y); }
这个Lambda表达式包含两个参数x和y,我们可以在代码块中使用这两个参数执行一些操作。
4. 简化Lambda表达式
如果Lambda表达式只包含一个参数,并且这个参数的类型可以被推断出来,那么可以省略参数的类型。例如:
x -> { System.out.println("Hello, " + x); }
如果Lambda表达式只包含一个语句,并且这个语句的返回值可以被推断出来,那么可以省略代码块的大括号和return关键字。例如:
(x, y) -> x + y
在这个Lambda表达式中,我们省略了代码块的大括号和return关键字,因为它只包含一个语句,并且这个语句的返回值可以被推断出来。
5. 方法引用
Lambda表达式可以使用方法引用来调用已有的方法。(方法引用是一种简洁的语法形式,它允许你直接引用现有的方法并将其作为Lambda表达式传递。在Lambda表达式中,可以使用双冒号运算符(::)来引用现有的方法)例如:
x -> { System.out::println}
在这个Lambda表达式中,我们使用了System.out.println方法的方法引用。
通过这些不同的Lambda表达式写法,我们可以编写出简洁而易读的代码,实现对数据的处理和操作。Lambda表达式是Java 8引入的一项重要特性,它在简化代码的同时,也提高了代码的可读性和可维护性。
5. 注意事项
虽然Lambda表达式使得Java程序更加简洁、易读、易维护,但是在使用Lambda表达式时也需要注意一些细节问题。
- 需要函数式接口
Lambda表达式只能用于函数式接口,即只有一个抽象方法的接口。如果一个接口有多个抽象方法,则无法使用Lambda表达式。如果我们定义的接口不是函数式接口,则在编译时会报错。
- 捕获外部变量
Lambda表达式可以访问其外部的变量,这些变量可以是final的,也可以是实际上是final的。如果在Lambda表达式中尝试修改这些变量,则会在编译时报错。
- 类型推断
Lambda表达式的类型推断有时候可能会出现问题,特别是当Lambda表达式同时具有多个参数时。在这种情况下,我们需要显式地声明参数类型。例如:
BinaryOperator<Integer> add = (Integer a, Integer b) -> a + b;
在上面的代码中,我们声明了add变量的类型为BinaryOperator<Integer>,并显式地声明了Lambda表达式的两个参数的类型为Integer。
6. 总结
Lambda表达式是Java 8中一个重要的特性,它使得Java程序更加简洁、易读、易维护。Lambda表达式的使用非常灵活,可以用于函数式接口、Stream API、排序等场景。在使用Lambda表达式时需要注意一些细节问题,例如Lambda表达式需要函数式接口、Lambda表达式捕获外部变量、Lambda表达式的类型推断和Lambda表达式的性能问题等。
在实际开发中,合理地使用Lambda表达式可以使代码更加简洁、易读、易维护,并且可以提高程序的性能。Lambda表达式是现代Java编程的一个重要特性,如果你还不知道Lambda,赶紧学起来吧!