java8新特性——Lambda 表达式

函数式接口的重要属性是:我们能够使用 Lambda 实例化它们,Lambda 表达式让你能够将函数作为方法参数,或者将代码作为数据对待。Lambda 表达式的引入给开发者带来了不少优点:在 Java 8 之前,匿名内部类,监听器和事件处理器的使用都显得很冗长,代码可读性很差,Lambda 表达式的应用则使代码变得更加紧凑,可读性增强;Lambda 表达式使并行操作大集合变得很方便,可以充分发挥多核 CPU 的优势,更易于为多核处理器编写代码;

Lambda 表达式由三个部分组成:第一部分为一个括号内用逗号分隔的形式参数,参数是函数式接口里面方法的参数;第二部分为一个箭头符号:->;第三部分为方法体,可以是表达式和代码块。语法如下:

1. 方法体为表达式,该表达式的值作为返回值返回。

(parameters) -> expression

 

  1. 方法体为代码块,必须用 {} 来包裹起来,且需要一个 return 返回值,但若函数式接口里面方法返回值是 void,则无需返回值。
(parameters) -> { statements; }

例如,下面是使用匿名内部类和 Lambda 表达式的代码比较。

 

下面是用匿名内部类的代码:

button.addActionListener(new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

System.out.print("Helllo Lambda in actionPerformed");

}

});

下面是使用 Lambda 表达式后:

button.addActionListener(

\\actionPerformed 有一个参数 e 传入,所以用 (ActionEvent e)

(ActionEvent e)->

System.out.print("Helllo Lambda in actionPerformed")

);

上面是方法体包含了参数传入 (ActionEvent e),如果没有参数则只需 ( ),例如 Thread 中的 run 方法就没有参数传入,当它使用 Lambda 表达式后:

Thread t = new Thread(

\\run 没有参数传入,所以用 (), 后面用 {} 包起方法体

() -> {

 System.out.println("Hello from a thread in run");

}

);
通过上面两个代码的比较可以发现使用 Lambda 表达式可以简化代码,并提高代码的可读性。

为了进一步简化 Lambda 表达式,可以使用方法引用。例如,下面三种分别是使用内部类,使用 Lambda 表示式和使用方法引用方式的比较:

//1. 使用内部类

Function f = new Function(){

@Override

public String apply(Integer t) {

return null;

}

};

//2. 使用 Lambda 表达式

Function f2 = (t)->String.valueOf(t);

//3. 使用方法引用的方式

Function f1 = String::valueOf;

 

要使用 Lambda 表达式,需要定义一个函数式接口,这样往往会让程序充斥着过量的仅为 Lambda 表达式服务的函数式接口。为了减少这样过量的函数式接口,Java 8 在 java.util.function 中增加了不少新的函数式通用接口。例如:

 

Function:将 T 作为输入,返回 R 作为输出,他还包含了和其他函数组合的默认方法。

 

Predicate :将 T 作为输入,返回一个布尔值作为输出,该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(与、或、非)。

 

Consumer :将 T 作为输入,不返回任何内容,表示在单个参数上的操作。

例如,People 类中有一个方法 getMaleList 需要获取男性的列表,这里需要定义一个函数式接口 PersonInterface:

interface PersonInterface {

 public boolean test(Person person);

}

public class People {

 private List persons= new ArrayList();

 public List getMaleList(PersonInterface filter) {

 List res = new ArrayList();

 persons.forEach(

 (Person person) ->

 {

 if (filter.test(person)) {//调用 PersonInterface 的方法

 res.add(person);

 }

 }

 );

 return res;

 }

}

为了去除 PersonInterface 这个函数式接口,可以用通用函数式接口 Predicate 替代如下:

class People{

 private List persons= new ArrayList();

 public List getMaleList(Predicate predicate) {

 List res = new ArrayList();

 persons.forEach(

 person -> {

 if (predicate.test(person)) {//调用 Predicate 的抽象方法 test

 res.add(person);

 }

 });

 return res;

 }

}

 

你可能感兴趣的:(java8新特性——Lambda 表达式)