Java中的匿名函数/lambda表达式
Java中的匿名函数和lambda表达式是Java 8中添加的两个新功能。它们的出现使得Java程序员可以更方便地编写函数式代码,并且与其他函数式编程语言更加接近。本文将介绍匿名函数/lambda表达式的概念、语法和使用场景。
### 匿名函数
在Java 8之前,可以定义具名函数,但是匿名函数则不能存在。匿名函数是没有函数名的函数,它通常是一个直接在语句内部被定义和使用的函数。
Java 8之前,如果需要使用匿名函数,比如;对一个数组的每一个元素进行遍历并输出,常规的做法如下:
Arrays.asList("apple", "banana", "orange").forEach(new Consumer<String>() {
@Override
public void accept(String s) {
System.out.println(s);
}
});
在这个例子中,我们定义了一个实现了Consumer<String>接口中的accept()方法的匿名内部类,然后将它传递给forEach()方法。这样做的缺点是代码显得冗长,可读性不高。
Java 8开发者引入了lambda表达式语法,使得匿名函数可以更简洁和易于编写。
### Lambda表达式
Lambda表达式是一个匿名函数,它可以被传递作为参数,比如用于排序、map、reduce、filter等方法。Lambda表达式可以被视为简洁的匿名函数定义,该定义执行返回单个值。
Lambda表达式可以由以下部分组成:
- 形式参数列表: 此处暂时认为就是方法参数,有时候也可以省略不写,如没有参数的情况:() -> System.out.println("Hello World!");
- 箭头(->)符号: 分割参数列表与Lambda表达式的主体部分。
- 主体部分: Lambda表达式执行的主体部分可以是表达式(表达式语句)或语句块(包含多个语句)。
有一些例子如下:
// 格式1: 有输入参数,有输出
(int a, int b) -> { return a + b; }
// 格式2: 有输入参数,无输出
(String message) -> { System.out.println(message); }
// 格式3: 无输入参数,有输出
() -> 42
// 格式4: 语句块形式
Player p1 = new Player();
players.forEach((Player p) -> {
p.incrementScore();
p1.decrementScore();
});
可以看到,在表达式主体部分里,也可以增加多个语句,使用大括号{}来包括语句块。
Lambda表达式可以转换为函数式接口,只要接口只有一个抽象方法,该接口即可称为函数式接口。Lambda表达式不会生成一个类文件。
### 使用场景
1. 事件监听器
事件监听器需要处理各种类型的事件,通常实现一个事件监听器接口,比如ActionListener接口,调用这个接口的addActionListener()方法,当事件发生时就会调用实现的监听器进行处理,实现匿名函数/lambda表达式可以使代码更简练。
button.addActionListener((event) -> {
System.out.println("Button clicked !");
});
2. 集合操作
匿名函数/lambda表达式非常适合集合中的操作,比如map、reduce、filter等。
List<String> fruits = Arrays.asList("apple", "banana", "orange", "pear");
// 输出首字母大写的水果名称
fruits.stream()
.map(fruit -> Character.toUpperCase(fruit.charAt(0)) + fruit.substring(1))
.forEach(System.out::println);
3. 并行处理
Java 8对并行处理进行了优化,可以使用parallelStream()方法实现多线程,在集合中使用匿名函数/lambda表达式可以很容易地实现并行处理。
List<String> words = ... long count = words.parallelStream().filter(w -> w.length() > 12).count();
### 总结
Java的匿名函数和lambda表达式是Java 8中的新功能,它们使Java编程更加简洁和容易理解。Lambda表达式是一个无类型的语法,可以被用作接口的实现。
在使用匿名函数/lambda表达式时需要注意语法、作用域和线程安全问题,但是使用好了它们能大大提高代码的表现力和可读性。
