Java 8引入了许多重要的新特性,其中最引人注目的就是Lambda表达式。Lambda是
Java编程语言中对函数式编程的一种支持。Lambda表达式也被称为闭包或匿名函数Lambda表达式能够实现更加灵活和简洁的代码。接下来让我们一一介绍认识他。
什么是Lambda 表达式
Lambda 表达式(lambda expression)是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码。
Lambda 表达式与匿名内部类
匿名内部类,就是没有名字的一种嵌套类。它是Java对类的定义方式之一。在实际开发中,如果一个接口/类/抽象类的方法的某个实现方式在程序中只会执行一次。此时可以使用匿名内部类的方式,可以无需创建新的类,减少代码冗余。函数式接口是可以使用匿名内部类进行创建实例,而lambda可以简化使用匿名内部类创建。
匿名内部类使用举例:
假设当前有一个接口,接口中只有一个方法:
public interface Iface{
void show();
}
为了使用该接口的show方法,我们需要去创建一个实现类,同时书写show方法的具体实现方式
public class Iface01 implements Iface{
@Override
public void show() {
System.out.println("I'm a impl class...");
}
}
如果我们全程只会使用这个类一次,那么为了这一次的使用去创建一个类就太过麻烦,因此我们可以这样来写:
public static void main(String[] args) {
Iface iface01= new Iface() {
@Override
public void show() {
System.out.println("这里使用了匿名内部类");
}
};
//调用接口方法
iface01.show();
}
此外在创建线程的时候我们也可以用匿名内部类来简化代码:
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("线程running...");
}
};
new Thread(runnable).start();
Lambda 表达式与函数式接口
上面我们说到Lambda 表达式(lambda expression)是一个匿名函数,那么lambda是函数式编程吗,在传统的函数式编程中,lambda表达式类型是函数,而在java中一切都是对象,lambda也不例外,所以他必须依赖特殊的对象类型-函数式接口来实现函数式编程。
什么是函数式(Functional)接口
函数式接口就是只有一个抽象方法的接口,同时,只有函数式接口可以使用Lambda表达式。在java.util.function包下定义了Java 8 的丰富的函数式接口
如在java8中Runnable接口就是一个典型的函数式接口
@FunctionalInterface
public interface Runnable {
/**
* When an object implementing interface <code>Runnable</code> is used
* to create a thread, starting the thread causes the object's
* <code>run</code> method to be called in that separately executing
* thread.
* <p>
* The general contract of the method <code>run</code> is that it may
* take any action whatsoever.
*
* @see java.lang.Thread#run()
*/
public abstract void run();
}
Lambda 表达式:语法
“->”。这个操作符被称为Lambda操作符或箭头函数。Lambda表达式可以被分为两个部分:
左侧:指定了Lambda表达式需要的参数列表。
右侧:指定了Lambda体,即抽象方法的实现逻辑,也是Lambda表达式要执行的功能。
格式一:无参数,无返回值
() -> System.out.println("Hello Lambda!");
格式二:有一个参数,并且无返回值
(x) -> System.out.println(x)
格式三:若只有一个参数,小括号可以省略不写
x -> System.out.println(x)
格式四:有两个以上的参数,有返回值,并且 Lambda 体中有多条语句
Comparator<Integer> com = (x, y) -> {
System.out.println("函数式接口");
return Integer.compare(x, y);
};
格式五:若 Lambda 体中只有一条语句, return 和 大括号都可以省略不写
Comparator<Integer> com = (x, y) -> Integer.compare(x, y);
格式六:数据类型可以省略,因为可由编译器来进行“类型推断”
() -> System.out.println("Hello Lambda!");