欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

不知道面試會(huì)不會(huì)問(wèn)Lambda怎么用(推薦)

 更新時(shí)間:2019年04月20日 11:00:14   作者:邊緣煩惱  
這篇文章主要介紹了Lambda表達(dá)式用法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

我們先假設(shè)一個(gè)場(chǎng)景想象一下,當(dāng)一個(gè)項(xiàng)目出現(xiàn)bug的時(shí)候,恰巧這個(gè)時(shí)候需要你去修改,而當(dāng)你打開(kāi)項(xiàng)目之后,眼前的代碼讓你有一種特別嚴(yán)重的陌生感,你會(huì)不會(huì)慌?心里是不是瞬間就會(huì)噴涌而出各種想法:我這是打開(kāi)的啥語(yǔ)言的項(xiàng)目?還是我眼花看錯(cuò)了?難道是我過(guò)時(shí)了?這寫(xiě)的是個(gè)啥子玩意兒…

java8在14年就出來(lái)了,已經(jīng)很久了,但是還是有很多人沒(méi)用過(guò),包括我之前的同事都對(duì)這個(gè)不太熟悉,原因可能是多樣的,可能是老程序員覺(jué)得沒(méi)必要;也可能是性格使然,拒絕接受新的東西,一切守舊,能用就行;也可能是項(xiàng)目太老了,還在用JDK1.7,或者更老的版本,平時(shí)根本就接觸不到j(luò)ava8的寫(xiě)法,也不需要去接觸。

無(wú)論是什么原因,在新事物出現(xiàn)之后,沒(méi)有一股探險(xiǎn)精神,不去嘗試,不去結(jié)合自己的處境去思考,這樣下去就算天上掉餡餅也輪不到你啊。

這篇短文說(shuō)下Lambda表達(dá)式,有一定的編程基礎(chǔ)的小伙伴簡(jiǎn)單看下應(yīng)該就會(huì)明白,不僅僅寫(xiě)著舒服,更能提供你的工作效率,讓你有更多的時(shí)間帶薪劃水,自我提高,走向人生巔峰。

Lambda表達(dá)式

Lambda表達(dá)式可以理解為一種匿名函數(shù):沒(méi)有名稱(chēng)、有參數(shù)列表、函數(shù)主體、返回類(lèi)型,可能還會(huì)有異常的列表。

參數(shù) -> 主體

lambda表達(dá)式:(parameters) -> expression 或者是 (parameters) -> { statements; }

函數(shù)式接口

什么是函數(shù)式接口?

僅僅定義了一個(gè)抽象方法的接口,類(lèi)似于Predicate、Comparator和Runnable。

@FunctionalInterface 函數(shù)式接口都帶有這個(gè)注解,這個(gè)注解表示這個(gè)接口會(huì)被設(shè)計(jì)為函數(shù)式接口。

行為參數(shù)化

一個(gè)方法接受多個(gè)不同的行為作為參數(shù),并在內(nèi)部使用它們,完成不同行為的能力。

函數(shù)式接口可以做些什么?

Lambda表達(dá)式允許你直接以?xún)?nèi)聯(lián)的形式為函數(shù)式接口的抽象方法提供實(shí)現(xiàn),并且把整個(gè)表達(dá)式作為函數(shù)式接口的實(shí)例,也就是說(shuō),Lambda是函數(shù)式接口的一個(gè)具體實(shí)現(xiàn)。函數(shù)式接口和Lambda會(huì)在項(xiàng)目中寫(xiě)出更加簡(jiǎn)潔易懂的代碼。

接下來(lái)我們看下幾種函數(shù)式接口:

  1. java.util.function.Predicate:這個(gè)接口中定義了一個(gè)test的抽象方法,它接受泛型T對(duì)象,并返回一個(gè)boolean值,在你需要表示一個(gè)涉及類(lèi)型T的布爾表達(dá)式時(shí),就可以使用這個(gè)接口。
  2. java.util.function.Consumer:這個(gè)接口中定義了accept抽象方法,它接受泛型T的對(duì)象,沒(méi)有返回。如果你需要訪(fǎng)問(wèn)類(lèi)型T的對(duì)象,并執(zhí)行某些操作,可以用它。
  3. java.util.function.Function:這個(gè)接口定義了一個(gè)apply的方法,它接受一個(gè)泛型T的對(duì)象,并返回一個(gè)泛型R的對(duì)象,如果你需要定一個(gè)Lambda,將輸入對(duì)象的信息映射到輸出對(duì)象,就可以使用這個(gè)接口。
  4. ps:我們也可以自己定義一個(gè)自己需要的函數(shù)式接口。

這么說(shuō)實(shí)在是太生澀了,還是貼點(diǎn)代碼,讓大家都看看:

@FunctionalInterface
public interface Predicate<T> {
 //我只截取了部分代碼,test是這個(gè)接口唯一的抽象方法,話(huà)說(shuō)從java8開(kāi)始,接口中不僅 
 //僅只能有抽象方法了,實(shí)現(xiàn)的方法也可以存在,用default和static來(lái)修飾。
 boolean test(T t);
 default Predicate<T> and(Predicate<? super T> other) {
  Objects.requireNonNull(other);
  return (t) -> test(t) && other.test(t);
 }

。

接下來(lái),看下Lambda和函數(shù)式接口是怎么配合,一起快樂(lè)的工作的: 首先定義一個(gè)方法,這個(gè)方法的參數(shù)中有函數(shù)式接口:

private static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
 List<T> result = new ArrayList<>();
 for (T e : list) {
  if (predicate.test(e)) {
   result.add(e);
  }
 }
 return result;
}

接下來(lái)你就可以這么寫(xiě):

List<Apple> apples = filter(list, (Apple apple) -> "red".equals(apple.getColor()));

以上,filter方法的參數(shù)是一個(gè)泛型集合和Predicate,這個(gè)函數(shù)式接口中的抽象方法是接受一個(gè)對(duì)象并返回一個(gè)布爾值,所以L(fǎng)ambda我們可以寫(xiě)成參數(shù)是一個(gè)實(shí)體對(duì)象Apple,主體是一個(gè)返回boolean值的表達(dá)式,將這段Lambda作為參數(shù)傳給filter()方法,這也是java8的行為參數(shù)化特性。以上我們就可以挑選出紅蘋(píng)果。

使用了泛型,就代表著我們還可以復(fù)用這段代碼做些別的事情,挑選出你想要東東的:

List<String> stringList = filter(strList, StringUtils::isNoneBlank);

抽象方法的方法簽名和Lambda表達(dá)式的簽名是一一對(duì)應(yīng)的,如果你要應(yīng)用不同的Lambda表達(dá)式,就需要多個(gè)函數(shù)式接口,當(dāng)然了我也是可以自己定義的。

在java中只有引用類(lèi)型或者是原始類(lèi)型,這是由泛型內(nèi)部的實(shí)現(xiàn)方式造成的。因此,在Java里有一個(gè)將原始類(lèi)型轉(zhuǎn)換為對(duì)應(yīng)的引用類(lèi)型的機(jī)制,這個(gè)機(jī)制叫作裝箱(boxing)。相反的操作,也就是將引用類(lèi)型轉(zhuǎn)換為對(duì)應(yīng)的原始類(lèi)型,叫作拆箱(unboxing)。

Java還有一個(gè)自動(dòng)裝箱機(jī)制,也就是說(shuō)裝箱和拆箱操作是自動(dòng)完成的,但這在性能方面是要付出代價(jià)的。裝箱后的值本質(zhì)上就是把原始類(lèi)型包裹起來(lái),并保存在堆里。因此,裝箱后的值需要更多的內(nèi)存,并需要額外的內(nèi)存來(lái)搜索獲取被包裹的原始值。

針對(duì)于這一點(diǎn),java8中的函數(shù)式接口提供了單獨(dú)的接口,就是為了在輸入和輸出的時(shí)候避免自動(dòng)裝箱拆箱的操作,是不是很貼心。

一般情況下,在名稱(chēng)上我們就能看得出來(lái),一目了然。在原來(lái)的名稱(chēng)上會(huì)有原始類(lèi)型前綴。像Function接口針對(duì)輸出參數(shù)類(lèi)型的變形。比如說(shuō):ToIntFunction、IntToDoubleFunction等。

在必要的情況下,我們也可以自己定義一個(gè)函數(shù)式接口,請(qǐng)記住,(T,U) -> R的表達(dá)方式展示了對(duì)一個(gè)函數(shù)的簡(jiǎn)單描述,箭頭的的左側(cè)代表了參數(shù)類(lèi)型,右側(cè)代表著返回類(lèi)型,這里它代表一個(gè)函數(shù),具有兩個(gè)參數(shù),分別為泛型T和U,返回類(lèi)型為R。

函數(shù)式接口是不允許拋出 受檢異常(checked exception),但是有兩個(gè)方法可以?huà)伋霎惓#?/p>

  1. 定義一個(gè)自己的函數(shù)式接口,在唯一的抽象方法拋出異常;
  2. 用try-catch 將lambda 包起來(lái)。

類(lèi)型檢查

java7是通過(guò)泛型從上下文推斷類(lèi)型,lambda的類(lèi)型檢查是通過(guò)它的上下文推斷出來(lái)的。lambda會(huì)找到它所在的方法的方法簽名,也就是它的參數(shù),也就是他們說(shuō)的目標(biāo)類(lèi)型,再找到這個(gè)方法中定義的抽象方法,這個(gè)方法描述的函數(shù)描述符是什么?也就是這個(gè)方法是個(gè)什么樣的,接受什么參數(shù),返回什么。lambda也必須是符合這樣的。當(dāng)lambda拋出異常的時(shí)候,那個(gè)抽象方法也必須要拋出異常。
有了目標(biāo)類(lèi)型,那么同一個(gè)lambda就可以與不同的函數(shù)式接口聯(lián)系起來(lái)。只要他們的抽象方法簽名是一樣的。
例如:

Callable<Integer> c = () -> 42;
PrivilegedAction<Integer> p = () -> 42;

這兩個(gè)接口都是沒(méi)有參數(shù),且返回一個(gè)泛型T的函數(shù)。 void兼容規(guī)則 lambda的主題是一個(gè)語(yǔ)句表達(dá)式,和一個(gè)返回void的函數(shù)描述符兼容,包括參數(shù)列表, 比如下面:

// Predicate返回了一個(gè)boolean
Predicate<String> p = s -> list.add(s);
// Consumer返回了一個(gè)void
Consumer<String> b = s -> list.add(s);

在lambda中使用局部變量

final int local_value = 44;
Consumer<String> stringConsumer = (String s) -> {
   int new_local_value = s.length() + local_value;
  };

在lambda中可以無(wú)限制的使用實(shí)例變量和靜態(tài)變量,但是只能是final的,如果在表達(dá)式里面給變量賦值,就會(huì)編譯不通過(guò)。為什么會(huì)有這樣的呢?

因?yàn)閷?shí)例變量存儲(chǔ)在堆中,局部變量存儲(chǔ)在棧中,lambda是在一個(gè)線(xiàn)程中,如果lambda可以直接訪(fǎng)問(wèn)局部變量,lambda的線(xiàn)程可能會(huì)在分配該變量的線(xiàn)程將這個(gè)變量回收之后,再去訪(fǎng)問(wèn)該變量。在訪(fǎng)問(wèn)局部變量的時(shí)候,實(shí)際上是訪(fǎng)問(wèn)他的副本,而不是原始變量。

方法引用

方法引用,方法目標(biāo)實(shí)體放在::的前面,方法名放在后面。比如 Apple::getWeight,不需要括號(hào)。

構(gòu)造函數(shù)是可以利用它的名稱(chēng)和關(guān)鍵字 new來(lái)創(chuàng)建一個(gè)引用。

//Supplier也是一個(gè)函數(shù)式接口,唯一的抽象方法不接受參數(shù),直接返回一個(gè)對(duì)象
Supplier<Apple> sup = Apple::new;
  Apple apple = sup.get();

但是如果是有參數(shù)的呢?

//一個(gè)參數(shù)
Function<Long, Apple> fun = Apple::new;
    Apple apple1 = fun.apply(110L);
//兩個(gè)參數(shù)
 BiFunction<Long, String, Apple> biFunction = Apple::new;
 Apple biApple = biFunction.apply(3L, "red");

但是如果有三個(gè)參數(shù)、四個(gè)參數(shù)呢?我們上面說(shuō)了怎么樣可以自定義一個(gè)自己需要的函數(shù)式接口。

@FunctionalInterface
public interface AppleWithParam<T, U, V, R> {
  R apply(T t, U u, V v);
}

總結(jié):

  1. java8中自帶的函數(shù)式接口,以及為了避免拆裝箱操作而產(chǎn)生的函數(shù)式接口的原始類(lèi)型轉(zhuǎn)化。
  2. 函數(shù)式接口就是僅僅定義一個(gè)抽象方法的接口。抽象方法的簽名(稱(chēng)為函數(shù)描述符) 描述了Lambda表達(dá)式的簽名。
  3. 只有在接受函數(shù)式接口的地方才可以使用Lambda表達(dá)式。
  4. 接口現(xiàn)在還可以擁有默認(rèn)方法,(就是類(lèi)沒(méi)有對(duì)方法進(jìn)行實(shí)現(xiàn)的時(shí)候,它實(shí)現(xiàn)的接口來(lái)提供默認(rèn)實(shí)現(xiàn)的方法)

以上所述是小編給大家介紹的Lambda表達(dá)式詳解整合,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!

相關(guān)文章

  • java設(shè)計(jì)模式之組合模式(Composite)

    java設(shè)計(jì)模式之組合模式(Composite)

    這篇文章主要為大家詳細(xì)介紹了java設(shè)計(jì)模式之組合模式Composite,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-01-01
  • Idea?中控制啟動(dòng)命令的詳細(xì)過(guò)程?區(qū)分環(huán)境案例詳解

    Idea?中控制啟動(dòng)命令的詳細(xì)過(guò)程?區(qū)分環(huán)境案例詳解

    這篇文章主要介紹了Idea?中控制啟動(dòng)命令的詳細(xì)過(guò)程?區(qū)分環(huán)境案例詳解,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-08-08
  • Java 如何實(shí)現(xiàn)POST(x-www-form-urlencoded)請(qǐng)求

    Java 如何實(shí)現(xiàn)POST(x-www-form-urlencoded)請(qǐng)求

    這篇文章主要介紹了Java 實(shí)現(xiàn)POST(x-www-form-urlencoded)請(qǐng)求,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java基礎(chǔ)面試題之volatile詳解

    Java基礎(chǔ)面試題之volatile詳解

    Volatile可以看做是輕量級(jí)的 Synchronized,它只保證了共享變量的可見(jiàn)性,下面這篇文章主要給大家介紹了關(guān)于Java基礎(chǔ)面試題之volatile的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • Java調(diào)用pyzbar解析base64二維碼過(guò)程解析

    Java調(diào)用pyzbar解析base64二維碼過(guò)程解析

    這篇文章主要介紹了Java調(diào)用pyzbar解析base64二維碼過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • SpringBoot+docker環(huán)境變量配置詳解

    SpringBoot+docker環(huán)境變量配置詳解

    這篇文章主要介紹了SpringBoot+docker環(huán)境變量配置詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • ChatGPT-4.0未來(lái)已來(lái) 你來(lái)不來(lái)

    ChatGPT-4.0未來(lái)已來(lái) 你來(lái)不來(lái)

    最近聽(tīng)說(shuō)了一個(gè)非?;鸬募夹g(shù)ChatGPT4.0,今天這篇文章就給大家介紹一下ChatGPT究竟是什么東東,不得不說(shuō)ChatGPT是真的強(qiáng),下面就讓我們一起了解究竟什么是ChatGPT吧
    2023-03-03
  • SpringMVC用XML方式實(shí)現(xiàn)AOP的方法示例

    SpringMVC用XML方式實(shí)現(xiàn)AOP的方法示例

    這篇文章主要介紹了SpringMVC用XML方式實(shí)現(xiàn)AOP的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Mybatis之a(chǎn)ssociation和collection用法

    Mybatis之a(chǎn)ssociation和collection用法

    這篇文章主要介紹了Mybatis之a(chǎn)ssociation和collection用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • try-cache-finally讀取文件錯(cuò)誤try-with-resources使用方法

    try-cache-finally讀取文件錯(cuò)誤try-with-resources使用方法

    這篇文章主要為大家介紹了try-cache-finally讀取文件錯(cuò)誤try-with-resources使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02

最新評(píng)論