Java8于2014年發(fā)布,其最重要的新特性,便是支持了lambda表達(dá)式。那么,什么是lambda表達(dá)式呢?我的理解是,lambda表達(dá)式是一個(gè)匿名函數(shù),可以賦值給一個(gè)變量。其他語言如JavaScript非強(qiáng)類型的可以直接賦值,但是,java中一切皆對(duì)象,賦給的值需要是“函數(shù)式接口”類型(Java8注解@FunctionalInterface標(biāo)記的接口,只有一個(gè)抽象方法的接口),當(dāng)然,普通的接口類型也可以,lambda充當(dāng)接口的實(shí)現(xiàn)類,如下圖Runnable接口。Java8還提供了很多函數(shù)式接口方便我們開發(fā),在java.util.function包中。

更多關(guān)于lambda表達(dá)是,可以參考本篇文章底部的“參考資料”,可以先看下Mingqi在知乎上的回答,Lambda 表達(dá)式有何用處?如何使用? - Mingqi的回答 - 知乎,以下是我的個(gè)人總結(jié)??傊?,java中l(wèi)ambda表達(dá)式雖然使得代碼相當(dāng)精簡(jiǎn),不過可讀性不高,后期很難維護(hù),個(gè)人不建議項(xiàng)目中使用lambda表達(dá)式。
lambda表達(dá)式最規(guī)范的形態(tài)是(parameters) ->{ statements; },其可以賦值給一個(gè)接口,如MyInterface i = (String s, Interger i) -> { Sysout.out.println(s + " " + i); }。當(dāng)然,參數(shù)類型可以省略。同時(shí)如果parameters只有一個(gè)參數(shù),可以省略小括號(hào),statements只有一條語句,可以省略花括號(hào)。如x -> System.out.println(x)。
lambda常用模式
OK,接下來試試lambda的用法。首先,我們說lambda需要賦值給接口類型,那么這里,我們定義一個(gè)接口,只有一個(gè)方法printAString()打印一個(gè)字符串。
public interface MyInterface {
void printAString (String s);
}

有了接口,一般我們需要新建一個(gè)實(shí)現(xiàn)類才能使用該接口,現(xiàn)在不用啦,用lambda搞定,如下,測(cè)試接口的實(shí)現(xiàn)。
import me.zebin.demo.lambdademo.service.MyInterface;
import org.junit.Test;
public class MyInterfaceTest {
@Test
public void testPrintAString(){
MyInterface i = x -> System.out.println(x);
i.printAString("hello lambda");
}
}
順利執(zhí)行。


嗯,在這里可以看到lambda的方便之處了吧,不用新建實(shí)現(xiàn)類就能通過lambda定義實(shí)現(xiàn)來調(diào)用方法了。
如果我們?cè)诮涌谛略鲆粋€(gè)方法呢,是否可行,如下,lambda報(bào)錯(cuò)了,因?yàn)閘ambda的接口只能有一個(gè)方法。


為了防止協(xié)同開發(fā)過程中,其他人在lambda接口中新增了方法導(dǎo)致別人的報(bào)錯(cuò)。可以在接口上加@FunctionalInterface,如下@FunctionalInterface只能有一個(gè)方法,否則編譯器會(huì)報(bào)錯(cuò)。

有了lambda,我們以后先線程就不用匿名內(nèi)部類了,因?yàn)镽unnable接口也是一個(gè)FunctionalInterface。
forEach循環(huán)
java的集合類,都實(shí)現(xiàn)了Iterable接口,該接口中定義了forEach方法,故結(jié)合類基本都能使用該方法。如下,該方法接受一個(gè)Consumer類型的接口,并執(zhí)行他的accept方法。Consumer是一個(gè)java.util.function中的@FunctionalInterface接口。

假設(shè)我們定義了一個(gè)List中有一組Person,遍歷輸出這些Person的姓名,那么可以使用lambda表達(dá)式如下執(zhí)行。
Person類如下:
public class Person {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
forEach打印測(cè)試如下:
public class PersonTest {
@Test
public void testPerson(){
// 構(gòu)造一個(gè)list
List<Person> l = new ArrayList<>();
l.add(new Person("zhangsan", 20));
l.add(new Person("lisi", 21));
// foreach 循環(huán)打印
l.forEach(x -> System.out.println(x.getName()));
}
}
運(yùn)行結(jié)果如下:

本篇就寫到這里啦,早上起來寫的,上班去。
參考資料
Lambda 表達(dá)式有何用處?如何使用? - Mingqi的回答 - 知乎
The Java? Tutorials(官方文檔)
猴子小皮球的簡(jiǎn)書