Java 函數(shù)式接口

2018-03-18 17:21 更新

Java Lambda - Java函數(shù)式接口


函數(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á)式的類型由編譯器推斷。

Java函數(shù)式接口定義

函數(shù)式接口是具有一個(gè)抽象方法的接口。

我們不能使用以下類型的方法來聲明一個(gè)函數(shù)式接口:

  • 默認(rèn)方法
  • 靜態(tài)方法
  • 從Object類繼承的方法

一個(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注釋

@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ù)與函數(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 Buildin函數(shù)式接口

Java 8在包java.util.function中有函數(shù)式接口

函數(shù)

表示接受類型T的參數(shù)并返回類型R的結(jié)果的函數(shù)。

public interface Function<T,R>{
   ...
   public R apply(T t);
   ...
}

BiFunction

表示一個(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);
   ...
}

BiPredicate

表示為兩個(gè)指定的參數(shù)返回 true false 的布爾函數(shù)。

public interface BiPredicate<T,U>{
   ...
   public boolean test(T t, U u);
   ...   
}

Consumer

表示接受參數(shù)并且不返回結(jié)果的操作。

public interface Consumer<T>{
   ...
   public void accept(T t);
   ...
}

BiConsumer

表示接受兩個(gè)參數(shù)并且不返回結(jié)果的操作。

public interface BiConsumer<T,U>{
   ...   
   public void accept(T t, U  u);
   ...   
}

Supplier

表示返回類型T的值的函數(shù)。

public interface Supplier<T>{
   ...
    public T get();
   ...
}

UnaryOperator

表示接受參數(shù)并返回相同類型的結(jié)果的函數(shù)。

public interface UnaryOperator<T>{
   ...
   public T  apply(T t);
   ...
}

BinaryOperator

表示一個(gè)函數(shù),它接受兩個(gè)參數(shù)并返回相同類型的結(jié)果。

public interface BinaryOperator<T>{
   ...
   public T apply(T t1, T t2);
   ...
}           

注意2

上述通用buildin函數(shù)式接口都是更專用的函數(shù)式接口的通用版本。

例如, IntConsumer Consumer<T> 的專用版本。

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)