函數(shù)式接口是具有一個(gè)方法的接口,用作lambda表達(dá)式的類型。
public interface ActionListener extends EventListener { public void actionPerformed(ActionEvent event); }
ActionListener
只有一個(gè)方法actionPerformed
。它是一個(gè)函數(shù)式接口。無論調(diào)用什么單一方法,只要Java編譯器具有兼容的方法簽名,Java編譯器就會(huì)將其匹配到您的lambda表達(dá)式。
lambda表達(dá)式表示函數(shù)式接口的實(shí)例。
lambda表達(dá)式的類型是一個(gè)函數(shù)式接口類型。
(String str) -> str.length()
str.length() 獲取一個(gè)String參數(shù)并返回其長度。
它的類型可以是任何具有抽象方法的函數(shù)接口類型,它使用String作為參數(shù)并返回int。
以下是這種函數(shù)式接口的示例:
@FunctionalInterface interface Processor { int getStringLength(String str); }
我們可以為其函數(shù)式接口實(shí)例賦值lambda表達(dá)式。
Processor stringProcessor = (String str) -> str.length();
在下面的代碼中,我們?yōu)槠浜瘮?shù)接口賦值一個(gè)lambda表達(dá)式。然后我們通過調(diào)用函數(shù)接口中定義的方法來執(zhí)行l(wèi)ambda表達(dá)式,并傳入一個(gè)參數(shù)。
public class Main { public static void main(String[] argv) { Processor stringProcessor = (String str) -> str.length(); String name = "Java Lambda"; int length = stringProcessor.getStringLength(name); System.out.println(length); } } @FunctionalInterface interface Processor { int getStringLength(String str); }
上面的代碼生成以下結(jié)果。
lambda表達(dá)式本身不能用作獨(dú)立的表達(dá)式。
lambda表達(dá)式的類型由編譯器推斷。
函數(shù)式接口是具有一個(gè)抽象方法的接口。
我們不能使用以下類型的方法來聲明一個(gè)函數(shù)式接口:
一個(gè)函數(shù)式接口可以重新聲明Object類中的方法。該方法不被視為抽象方法。因此,我們可以聲明lambda表達(dá)式使用的另一種方法。
考慮 java.util
包中的Comparator類,如下所示:
package java.util; @FunctionalInterface public interface Comparator<T> { // An abstract method declared in the functional interface int compare(T o1, T o2); // Re-declaration of the equals() method in the Object class boolean equals(Object obj); ... }
Comparator接口有兩個(gè)抽象方法: compare()
和 equals()
。
equals()
方法是Object類中的 equals()
方法的重新聲明。
@FunctionalInterface
注釋在java.lang包中定義。我們可以選擇使用它來標(biāo)記一個(gè)函數(shù)式接口。
如果注釋 @FunctionalInterface
在非函數(shù)式接口或其他類型(如類)上注釋,則會(huì)發(fā)生編譯時(shí)錯(cuò)誤。
具有一個(gè)抽象方法的接口仍然是一個(gè)功能接口,即使我們不用 @FunctionalInterface
注釋。
public class Main { public static void main(String[] argv) { Processor stringProcessor = (String str) -> str.length(); String name = "Java Lambda"; int length = stringProcessor.getStringLength(name); System.out.println(length); } } @FunctionalInterface interface Processor { int getStringLength(String str); }
上面的代碼生成以下結(jié)果。
我們可以使用類型參數(shù)與函數(shù)式接口來創(chuàng)建通用函數(shù)式接口。
以下代碼創(chuàng)建具有一個(gè)類型參數(shù)T的通用函數(shù)式參數(shù)函數(shù)接口。
@FunctionalInterface public interface Comparator<T> { int compare(T o1, T o2); }
以下代碼使用抽象通用方法定義非通用函數(shù)式接口:
@FunctionalInterface public interface Processor { <T> void process(T[] list); }
Java 8在包java.util.function中有函數(shù)式接口
T
的參數(shù)并返回類型R
的結(jié)果的函數(shù)。public interface Function<T,R>{ ... public R apply(T t); ... }
表示一個(gè)函數(shù),它接受類型T和U的兩個(gè)參數(shù),并返回類型R的結(jié)果。
public interface BiFunction<T,U,R>{ ... public R apply(T t, U u); ... }
表示為指定參數(shù)返回 true
或 false
的布爾函數(shù)。
public Predicate<T> { ... public boolean test(T t); ... }
表示為兩個(gè)指定的參數(shù)返回 true
或 false
的布爾函數(shù)。
public interface BiPredicate<T,U>{ ... public boolean test(T t, U u); ... }
表示接受參數(shù)并且不返回結(jié)果的操作。
public interface Consumer<T>{ ... public void accept(T t); ... }
表示接受兩個(gè)參數(shù)并且不返回結(jié)果的操作。
public interface BiConsumer<T,U>{ ... public void accept(T t, U u); ... }
表示返回類型T的值的函數(shù)。
public interface Supplier<T>{ ... public T get(); ... }
表示接受參數(shù)并返回相同類型的結(jié)果的函數(shù)。
public interface UnaryOperator<T>{ ... public T apply(T t); ... }
表示一個(gè)函數(shù),它接受兩個(gè)參數(shù)并返回相同類型的結(jié)果。
public interface BinaryOperator<T>{ ... public T apply(T t1, T t2); ... }
上述通用buildin函數(shù)式接口都是更專用的函數(shù)式接口的通用版本。
例如, IntConsumer
是 Consumer<T>
的專用版本。
更多建議: