|
| 1 | +JDK8--Lambda表达式 |
| 2 | +=== |
| 3 | +## 1.什么是Lambda表达式 |
| 4 | +**Lambda表达式实质上是一个可传递的代码块,Lambda又称为闭包或者匿名函数,是函数式编程语法,让方法可以像普通参数一样传递** |
| 5 | + |
| 6 | +## 2.Lambda表达式语法 |
| 7 | +```(参数列表) -> {执行代码块}``` |
| 8 | +<br>参数列表可以为空```()->{}``` |
| 9 | +<br>可以加类型声明比如```(String para1, int para2) -> {return para1 + para2;}```我们可以看到,lambda同样可以有返回值. |
| 10 | +<br>在编译器可以推断出类型的时候,可以将类型声明省略,比如```(para1, para2) -> {return para1 + para2;}``` |
| 11 | +<br>(lambda有点像动态类型语言,并且lambda在字节码层面是用invokedynamic实现的,而这条指令就是为了让JVM更好的支持运行在其上的动态类型语言) |
| 12 | + |
| 13 | +## 3.函数式接口 |
| 14 | +在了解Lambda表达式之前,有必要先了解什么是函数式接口```(@FunctionalInterface)```<br> |
| 15 | +**函数式接口指的是有且只有一个抽象(abstract)方法的接口**<br> |
| 16 | +当需要一个函数式接口的对象时,就可以用Lambda表达式来实现,举个常用的例子: |
| 17 | +<br> |
| 18 | +``` |
| 19 | + Thread thread = new Thread(() -> { |
| 20 | + System.out.println("This is JDK8's Lambda!"); |
| 21 | + }); |
| 22 | +``` |
| 23 | +这段代码和函数式接口有啥关系?我们回忆一下,Thread类的构造函数里是不是有一个以Runnable接口为参数的? |
| 24 | +``` |
| 25 | +public Thread(Runnable target) {...} |
| 26 | +
|
| 27 | +/** |
| 28 | + * Runnable Interface |
| 29 | + */ |
| 30 | +@FunctionalInterface |
| 31 | +public interface Runnable { |
| 32 | + public abstract void run(); |
| 33 | +} |
| 34 | +``` |
| 35 | +到这里大家可能已经明白了,**Lambda表达式相当于一个匿名类或者说是一个匿名方法**。上面Thread的例子相当于 |
| 36 | +``` |
| 37 | + Thread thread = new Thread(new Runnable() { |
| 38 | + @Override |
| 39 | + public void run() { |
| 40 | + System.out.println("Anonymous class"); |
| 41 | + } |
| 42 | + }); |
| 43 | +``` |
| 44 | +也就是说,上面的lambda表达式相当于实现了这个run()方法,然后当做参数传入(个人感觉可以这么理解,lambda表达式就是一个函数,只不过它的返回值、参数列表都 |
| 45 | +由编译器帮我们推断,因此可以减少很多代码量)。 |
| 46 | +<br>至此大家应该明白什么是函数式接口以及函数式接口和lambda表达式之间的关系了。在JDK8中修改了接口的规范, |
| 47 | +目的是为了在给接口添加新的功能时保持向前兼容(个人理解),比如一个已经定义了的函数式接口,某天我们想给它添加新功能,那么就不能保持向前兼容了, |
| 48 | +因为在旧的接口规范下,添加新功能必定会破坏这个函数式接口[(JDK8中接口规范)]() |
| 49 | +<br> |
| 50 | +除了上面说的Runnable接口之外,JDK中已经存在了很多函数式接口 |
| 51 | +比如(当然不止这些): |
| 52 | +- ```java.util.concurrent.Callable``` |
| 53 | +- ```java.util.Comparator``` |
| 54 | +- ```java.io.FileFilter``` |
| 55 | +<br>**关于JDK中的预定义的函数式接口** |
| 56 | + |
| 57 | +- JDK在```java.util.function```下预定义了很多函数式接口 |
| 58 | + - ```Function<T, R> {R apply(T t);}``` 接受一个T对象,然后返回一个R对象,就像普通的函数。 |
| 59 | + - ```Consumer<T> {void accept(T t);}``` 消费者 接受一个T对象,没有返回值。 |
| 60 | + - ```Predicate<T> {boolean test(T t);}``` 判断,接受一个T对象,返回一个布尔值。 |
| 61 | + - ```Supplier<T> {T get();} 提供者(工厂)``` 返回一个T对象。 |
| 62 | + - 其他的跟上面的相似,大家可以看一下function包下的具体接口。 |
| 63 | + |
| 64 | +## 4.[方法引用]() |
0 commit comments