Java 函数式编程 - Lambda 表达式
Java 函数式编程 - Lambda 表达式
Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
Lambda 表达式其实是实现函数式接口的一种语法糖。
使用 Lambda 表达式可以使代码变的更加简洁紧凑。
语法
(parameters) -> expression
或
(parameters) ->{ statements; }
以下是 lambda 表达式的重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以自动推断参数类型。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个值。
示例
// 随机数生成函数
Supplier<Double> supplier = () -> Math.random();
// 偶数判断函数
Predicate<Integer> predicate = num -> num % 2 == 0;
// 字符串打印函数
Consumer<String> consumer = str -> System.out.println(str);
// 整数转字符串函数
Function<Integer, String> function = num -> String.valueOf(num);
// 整数相加函数
BiFunction<Integer, Integer, Integer> biFunction = (a, b) -> a + b;
// 等效,显式定义参数类型
BiFunction<Integer, Integer, Integer> biFunction2 = (Integer a, Integer b) -> a + b;
// 等效,有大括号
BiFunction<Integer, Integer, Integer> biFunction3 = (a, b) -> {
return a + b;
};
匿名内部类的等效写法
// 随机数生成函数
Supplier<Double> s1 = () -> Math.random();
// 等效
Supplier<Double> s2 = new Supplier<Double>() {
@Override
public Double get() {
return Math.random();
}
};
用例
一个简单计算器例子
public class LambdaUsage {
// 操作符 -> 计算函数
private static final Map<String, BiFunction<Double, Double, Double>> operationMap = initOperationMap();
private static Map<String, BiFunction<Double, Double, Double>> initOperationMap() {
Map<String, BiFunction<Double, Double, Double>> map = new HashMap<>();
map.put("+", (a, b) -> a + b);
map.put("-", (a, b) -> a - b);
map.put("*", (a, b) -> a * b);
map.put("/", (a, b) -> a / b);
return map;
}
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while (true) {
double num1 = input.nextDouble();
String operator = input.next();
double num2 = input.nextDouble();
BiFunction<Double, Double, Double> operation = operationMap.get(operator);
if (operation == null) {
System.err.println("未知的操作符");
continue;
}
calculate(num1, num2, operation);
}
}
/**
* 执行计算操作
*
* @param num1 操作数1
* @param num2 操作数2
* @param operation 操作函数
*/
private static void calculate(double num1, double num2, BiFunction<Double, Double, Double> operation) {
Double result = operation.apply(num1, num2);
System.out.println("结果:" + result);
}
}
1 + 2
结果:3.0
8 - 5
结果:3.0
2 * 45
结果:90.0
75 / 15
结果:5.0
方法引用
方法引用是 Lambda 表达式的一种语法糖,有以下几种类型:
对象::实例方法
将 lambda 的参数当做方法的参数使用
objectName::instanceMethod
示例:
Consumer<String> c1 = System.out::println;
// 等效
Consumer<String> c2 = (x) -> System.out.println(x);
类::静态方法
将 lambda 的参数当做方法的参数使用
ClassName::staticMethod
示例:
Function<Integer, String> f1 = String::valueOf;
// 等效
Function<Integer, String> f2 = (x) -> String.valueOf(x);
类::实例方法
将 lambda 的第一个参数当做方法的调用者,其他的参数作为方法的参数
ClassName::instanceMethod
示例:
BiPredicate<String, String> p1 = String::equals;
// 等效
BiPredicate<String, String> p2 = (x, y) -> x.equals(y);
构造函数
ClassName::new
示例:
// 无参构造函数
Supplier<User> s1 = User::new;
// 等效
Supplier<User> s2 = () -> new User();
// 有参构造函数
Function<Integer, User> f1 = User::new;
// 等效
Function<Integer, User> f2 = id -> new User(id);
// 创建数组
IntFunction<int[]> s3 = int[]::new;
// 等效
IntFunction<int[]> s4 = size -> new int[size];

浙公网安备 33010602011771号