Lambda表达式是在java规范提案JSR 335中定义的,Java 8 中引入了Lambda表达式,并被认为是Java 8最大的新特性,Lambda表达式促进了函数式编程,简化了Java编程开发。

1、背景介绍:

1)匿名内部类:

在Java中,匿名内部类一般适用于那些在Java应用中只会出现一次的实现类,举个例子,在标准的Swing或JavaFX应用中,有很多键盘和鼠标的事件处理程序,一般情况下,你不需要写一个单独的事件处理类,而是使用如下方式(有Swing编程经验的应该很熟悉吧)

JButton testButton = new JButton("Test Button");
testButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent ae)
{
System.out.println("Click Detected by Anon Class");
}
});

不这样做的话,你需要针对每一个事件写一个单独的ActionListener接口的实现类,这样的代码并不优雅,因为仅仅为了定义一个方法就需要附加写一大堆的代码。通常,哪里需要,就在哪里创建对应的匿名内部类,这样的代码可读性会更强。

2)函数式接口:

在Java 8中,如果一个接口只有一个抽象方法,我们成为函数式接口。在java8之前,我们可以使用匿名内部类来去实现这样的接口,在java8后,对于函数式接口通常使用lambda来实现。

testButton.addActionListener((e) ->
{
System.out.println("Click Detected by Anon Class");
});

2、Lambda表达式语法:

parameter -> expression body

主要组成:参数列表 + 箭头 + 表达式体,如 (int x, int y) -> x + y

其中,表达式体可以是一条表达式,也可以是一个语句块(多条代码语句);

Lambda表达式具有如下特征:

  • 【可选】类型声明:参数的类型不需要声明,编译器可以根据参数值推断出其类型;
  • 【可选】括号:单个参数的话,不需要用圆括号包围参数,当然,对于多个参数或无参数的话,括号是需要的;
  • 【可选】花括号:如果表达式主体只有一条语句的话,不需要用花括号包围,当然,对于多条语句,花括号是需要的;
  • 【可选】return关键字:如果表达式主体是单一表达式,return关键字可以不写,编译器可以自动返回该值,当然,如果写了return,则需要加上花括号;
package lambda;

/**
* LambdaTest
*
* @author Pi Chen
* @version V1.0.0, 2016年9月19日
* @see
* @since V1.0.0
*/
public class LambdaTest
{
public static void main(String args[])
{
LambdaTest tester = new LambdaTest();

// 有参数类型
MathOperation addition = (int a, int b) -> a + b;

// 无参数类型
MathOperation subtraction = (a, b) -> a - b;

// 有花括号,有return关键字
MathOperation multiplication = (int a, int b) -> {
return a * b;
};

// 无花括号,无return关键字,单一表达式情况
MathOperation division = (int a, int b) -> a / b;

// MathOperation调用示例
System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
System.out.println("10 / 5 = " + tester.operate(10, 5, division));

// 有括号
GreetingService greetService1 = message -> System.out.println("Hello " + message);

// 无括号,单个参数情况
GreetingService greetService2 = (message) -> System.out.println("Hello " + message);

// GreetingService调用示例
greetService1.sayMessage("Mahesh");
greetService2.sayMessage("Suresh");

//有括号, 无参情况
Runnable runTest = () -> System.out.println("Running");
//Runnable调用示例
runTest.run();
}

// 内部接口
interface MathOperation
{
int operation(int a, int b);
}

interface GreetingService
{
void sayMessage(String message);
}

interface Runnable
{
void run();
}

private int operate(int a, int b, MathOperation mathOperation)
{
return mathOperation.operation(a, b);
}
}

说明:

  • Lambda表达式主要用于定义一个函数式接口(functional interface:一个只包含一个抽象方法的接口)的内联实现,在上面的例子中,我们使用了各种类型的Lambda表达式来实现MathOperation接口的operation方法,接着又实现了GreetingService接口的sayMessage方法,Runnable接口的run方法;
  • Lambda表达式消除了匿名类的使用并且赋予Java简单且强大的函数式编程能力;