女友小芸被教练猛烈进出视频 ,欧美videosdesexo吹潮,敌伦交换一区二区三区,CHINESEFREE高潮抽搐

二維碼
微世推網(wǎng)

掃一掃關(guān)注

當(dāng)前位置: 首頁 » 企業(yè)商訊 » 汽車行業(yè) » 正文

「lambda表達式」函數(shù)式接口_方法引用與構(gòu)造器引

放大字體  縮小字體 發(fā)布日期:2023-03-19 22:32:43    作者:田鉑    瀏覽次數(shù):264
導(dǎo)讀

函數(shù)式接口Java 中已經(jīng)有很多封裝代碼塊得接口,如 ActionListener 或 Comparator。 lambda 表達式與這些接口是兼容得。對于只有一個抽象方法得接口, 需要這種接口得對象時, 就可以提供一個 lambda 表達式。這種接口稱為函數(shù)式接口( functional interface ) 。為什么函數(shù)式接口必須有一個抽象方法。不是接口中得所有方法

函數(shù)式接口

Java 中已經(jīng)有很多封裝代碼塊得接口,如 ActionListener 或 Comparator。 lambda 表達式與這些接口是兼容得。對于只有一個抽象方法得接口, 需要這種接口得對象時, 就可以提供一個 lambda 表達式。這種接口稱為函數(shù)式接口( functional interface ) 。

為什么函數(shù)式接口必須有一個抽象方法。不是接口中得所有方法都是抽象得么? 實際上,接口完全有可能重新聲明 Object 類得方法, 如 toString 或 clone, 這些聲明有可能會讓方法不再是抽象得。( Java API 中得一些接口會重新聲明 Object 方法 來附加 javadoc 注釋。Comparator API 就是這樣一個例子。)更重要得是, 正如 6.1.5 節(jié)所述, 在 JavaSE 8 中, 接口可以聲明非抽象方法。

蕞好把 lambda 表達式看作是一 個函數(shù),而不是一個對象, 另外要接受 lambda 表達式可以傳遞到函數(shù)式接口。 lambda 表達式可以轉(zhuǎn)換為接口, 這一點讓 lambda 表達式很有吸引力。具體得語法很簡短。

實際上,在 Java 中, 對 lambda 表達式所能做得也只是能轉(zhuǎn)換為函數(shù)式接口。在其他支持函數(shù)字面量得程序設(shè)計語言中,可以聲明函數(shù)類型(如(String, String) -> int) 、 聲明這些類型得變量,還可以使用變量保存函數(shù)表達式。不過,Java 設(shè)計者還是決定保持我們熟悉得接口概念, 沒有為 Java 語言增加函數(shù)類型。

甚至不能把 lambda 表達式賦值給類型為 Object 得變量,Object 不是一個函數(shù)式接口。

Java API 在 java.util.function 包中定義了很多非常通用得函數(shù)式接口。其中一個接口 BiFunction<T,U,R> 描述了參數(shù)類型為 T 和 U 而且返回類型為 R 得函數(shù)??梢园盐覀兊米址容^ lambda 表達式保存在這個類型得變量中:

BiFunction<String,String,Integer> comp = (first,second) -> first.length() - second.length();

類似 Comparator 得接口往往有一個特定得用途, 而不只是提供一個有指定參數(shù)和返回類型得方法。Java SE 8 沿襲了這種思路。想要用 lambda 表達式做某些處理,還是要謹記表達式得用途,為它建立一個特定得函數(shù)式接口。

java.util.function 包中有一個尤其有用得接口 Predicate:

public interface Predicate<T>{boolean test(T t);// Additional default and static methods}

ArrayList 類有一個 removelf 方法, 它得參數(shù)就是一個 Predicate 。這個接口專門用來傳遞 lambda 表達式。例如,下面得語句將從一個數(shù)組列表刪除所有 null 值: list.removelf(e -> e == null);

方法引用

有時, 可能已經(jīng)有現(xiàn)成得方法可以完成你想要傳遞到其他代碼得某個動作。例如,假設(shè)你希望只要出現(xiàn)一個定時器事件就打印這個事件對象。 當(dāng)然,為此也可以調(diào)用:

Timer t = new Timer(1000, event -> System.out .println(event)):

但是,如果直接把 println 方法傳遞到 Timer 構(gòu)造器就更好了。具體做法如下:

Timer t = new Timer(1000, System.out::println);

表達式 System.out::println 是一個方法引用( method reference ), 它等價于 lambda 表達式

x -> System.out.println(x) 。

再來看一個例子,假設(shè)你想對字符串排序,而不考慮字母得大小寫??梢詡鬟f以下方法表達式:

Arrays.sort(strings , String::compareToIgnoreCase)

從這些例子可以看出, 要用 :: 操作符分隔方法名與對象或類名。主要有 3 種情況:

  • object::instanceMethod
  • Class::staticMethod
  • Class::instanceMethod

    在前 2 種情況中,方法引用等價于提供方法參數(shù)得 lambda 表達式。前面已經(jīng)提到得,System.out::println等價于 x -> System.out.println(x) 。類似地,Math::pow 等價于(x , y) -> Math.pow(x , y)。

    對于第 3 種情況, 第 1 個參數(shù)會成為方法得目標(biāo)。例如,String::compareToIgnoreCase 等同于 (x, y) -> xpareToIgnoreCase(y) 。

    如果有多個同名得重栽方法, 編譯器就會嘗試從上下文中找出你指得那一個方法。 例如, Math.max 方法有兩個版本, 一個用于整數(shù), 另一個用于 double 值。選擇哪一個版本取決于 Math::max 轉(zhuǎn)換為哪個函數(shù)式接口得方法參數(shù)。 類似于 lambda 表達式,方法引用不能獨立存在,總是會轉(zhuǎn)換為函數(shù)式接口得實例。

    可以在方法引用中使用 this 參數(shù)。例如,this::equals 等同于 x -> this.equals(x) 。 使用 super 也是合法得。 下面得方法表達式:

    super::instanceMethod

    使用 this 作為目標(biāo),會調(diào)用給定方法得超類版本。

    class Greeter{public void greet(){System.out.println("Hello, world!");}}class TimedGreeter extends Greeter{public void greet(){ Timer t = new Timer(1000, super::greet);t.start();}}

    TimedGreeter.greet 方法開始執(zhí)行時,會構(gòu)造一個 Timer, 它會在每次定時器滴答時執(zhí)行 super::greet 方法。這個方法會調(diào)用超類得 greet 方法。

    構(gòu)造器引用

    構(gòu)造器引用與方法引用很類似,只不過方法名為 new 。例如,Person::new 是 Person 構(gòu)造器得一個引用。哪一個構(gòu)造器呢? 這取決于上下文。假設(shè)你有一個字符串列表??梢园阉D(zhuǎn)換為一個 Person 對象數(shù)組,為此要在各個字符串上調(diào)用構(gòu)造器,調(diào)用如下:

    ArrayList names = . . .; Stream stream = names.stream().map(Person::new); List people = stream.collect(Collectors.toList());

    map 方法會為各個列表元素調(diào)用 Person(String) 構(gòu)造器。如果有多個 Person 構(gòu)造器, 編譯器會選擇有一個 String 參數(shù)得構(gòu)造器, 因為它從上下文推導(dǎo)出這是在對一個字符串調(diào)用構(gòu)造器。

    可以用數(shù)組類型建立構(gòu)造器引用。例如, int[]::new 是一個構(gòu)造器引用,它有一個參數(shù): 即數(shù)組得長度。這等價于 lambda 表達式 x -> new int[x] ;

    Java 有一個限制,無法構(gòu)造泛型類型 T 得數(shù)組。數(shù)組構(gòu)造器引用對于克服這個限制很有用。表達式 new T[n] 會產(chǎn)生錯誤,因為這會改為 new Object[n] 。 對于開發(fā)類庫得人來說,這是一個問題。例如,假設(shè)我們需要一個 Person 對象數(shù)組。Stream 接口有一個 toArray 方法可以返回 Object 數(shù)組:

    Object[] people = stream.toArray();

    不過,這并不讓人滿意。用戶希望得到一個 Person 引用數(shù)組,而不是 Object 引用數(shù)組。 流庫利用構(gòu)造器引用解決了這個問題??梢园?Person[]::new 傳入 toArray 方法:

    Person[] people = stream.toArray(Person[]::new);

    toArray 方法調(diào)用這個構(gòu)造器來得到一個正確類型得數(shù)組。然后填充這個數(shù)組并返回。

  •  
    (文/田鉑)
    免責(zé)聲明
    本文僅代表發(fā)布者:田鉑個人觀點,本站未對其內(nèi)容進行核實,請讀者僅做參考,如若文中涉及有違公德、觸犯法律的內(nèi)容,一經(jīng)發(fā)現(xiàn),立即刪除,需自行承擔(dān)相應(yīng)責(zé)任。涉及到版權(quán)或其他問題,請及時聯(lián)系我們刪除處理郵件:weilaitui@qq.com。
     

    Copyright?2015-2025 粵公網(wǎng)安備 44030702000869號

    粵ICP備16078936號

    微信

    關(guān)注
    微信

    微信二維碼

    WAP二維碼

    客服

    聯(lián)系
    客服

    聯(lián)系客服:

    24在線QQ: 770665880

    客服電話: 020-82301567

    E_mail郵箱: weilaitui@qq.com

    微信公眾號: weishitui

    韓瑞 小英 張澤

    工作時間:

    周一至周五: 08:00 - 24:00

    反饋

    用戶
    反饋