Java 8 中带来了一个新的特色,lambda表达式。如果用过其它高级语言如scala,那就一定不会陌生。
1. Java中的lambda表达式
在程序中,lambda表达式是一个匿名方法,没有名称,也没有标识符。换句话说,lambda表达式是一个作为常量给出的无名函数,必须使用在正确的位置,通常作为其它函数的参数。lambda表达式最大的特色是它在它出现的上下文环境中执行。所以,一段相同的lambda可以在不同的环境中执行,结果可能是不一样的,这取决于你传递到的方法。
使用lambda表达式的好处就相当于函数式编程与面向对象编程的对比好处。面向对象编程是围绕着对象和实体,类才是头等公民,函数不是。在Java中,方法不能存在于对象之外,没有与实体或对象关联的方法毫无意义。
在函数式编程中,你可以定义一个方法,然后作为参数传递给其它方法。这是Java中一直缺少的特色,而在Java8中,lambda表达式实现了它。
1.1 lambda语法
典型的lambda表达式语法如下:
(x, y) -> x + y
根据不同的上下文环境,表达式代表的意义也不一样。上面表达式可以接受int、Integer、long或字符串,计算两个数的和或拼接字符串。
其它形式lambda表达式
(parameters) -> expression
or
(paramaters) -> {statements;}
or
() -> expression
1.2 lambda例子
一些常用到的lambda表达式例子
(int a, int b) -> a * b // 返回两数乘积
(a, b) -> a - b // 返回两数差值
() -> 99 // 一个方法,返回99
(String s) -> System.out.println(s) // 接收一个参数并输出
a -> a * 2 // 数字翻倍
c -> {// 一些逻辑语句}
1.3 lambda表达式特点
lambda表达式可以接收一些参数,即可以明确的指定参数类型,也可以由上下文自行推断;
多个参数必须使用括号,空括号表示无参数,单个参数不强制使用括号;
主体部分有多条语句必须使用大括号,单一语句不强制,返回类型由主体语句决定;
2. Java 8 功能接口
在了解lambda表达式与Java程序之间的关系之前,我们还应该知道功能接口。
单一抽象方法接口不是一个新的概念,它表示接口只有单一的方法。在Java8中使用一个新的注解:@FunctionalInterface来表示功能接口。
看下Runnable接口
@FunctionalInterface
public interface Runnable {
public abstract void run();
}
如果你在一个功能接口中添加一个新的方法,那么编译期就会错误。
功能接口与lambda表达式的关系?
我们知道lambda是一个匿名函数,它大多数是作为其它方法参数。而在Java中,方法重写或调用方法参数需要明确指定类型。所以,每个lambda表达式都必须转换成方法参数的类型。lambda表达式转换的类型始终是功能接口的类型。
用一个简单的例子来理解它:
常规写法
new Thread(new Runnable() {
@Override public void run() {
System.out.println("functional interface!");
}
}).start();
用lambda表达式
new Thread(() -> System.out.println("functional interface!")).start();
Runnable是一个功能接口,带有单一方法run(),当我们用lambda表达式去构建Thread,编译器会尝试将lambda表达式转为上面的常规代码。
总的来说,lambda表达式是功能接口实例,但它不包含任何信息,它的信息是靠上下文推导出来的。
3. Java 8 lambda表达式实例
下面例子是在日常编程中如何使用lambda表达式的
3.1 遍历列表
List<String> pointList = new ArrayList();
pointList.add("1");
pointList.add("2");
pointList.forEach(p -> System.out.println(p));
3.2 创建线程
new Thread(() -> System.out.println("functional interface!")).start();
3.3 对象排序
Employee[] employees = {
new Employee("David"),
new Employee("Naveen"),
new Employee("Alex"),
new Employee("Richard")};
System.out.println("Before Sorting Names: "+ Arrays.toString(employees));
Arrays.sort(employees, (e1, e2) -> e1.name.compareTo(e2.name));
// or
Arrays.sort(employees, Employee::nameCompare);
System.out.println("After Sorting Names "+Arrays.toString(employees));
输出
Before Sorting Names: [David, Naveen, Alex, Richard]
After Sorting Names [Alex, David, Naveen, Richard]
3.4 GUI编程添加事件
JButton button = new JButton("Submit");
button.addActionListener((e) -> {
System.out.println("Click event triggered !!");
});
这就是lambda表达式一些非常基础的使用方法。