Java 函数式接口

2018-03-18 17:21 更新

Java Lambda - Java函数式接口


函数式接口是具有一个方法的接口,用作lambda表达式的类型。

public interface ActionListener extends EventListener {
    public void actionPerformed(ActionEvent event);
}

ActionListener 只有一个方法actionPerformed。它是一个函数式接口。无论调用什么单一方法,只要Java编译器具有兼容的方法签名,Java编译器就会将其匹配到您的lambda表达式。

lambda表达式表示函数式接口的实例。

lambda表达式的类型是一个函数式接口类型。

(String str) -> str.length() str.length() 获取一个String参数并返回其长度。

它的类型可以是任何具有抽象方法的函数接口类型,它使用String作为参数并返回int。

以下是这种函数式接口的示例:

@FunctionalInterface
interface Processor  {
    int  getStringLength(String str);
}

我们可以为其函数式接口实例赋值lambda表达式。

Processor stringProcessor = (String str) -> str.length();

例子

在下面的代码中,我们为其函数接口赋值一个lambda表达式。然后我们通过调用函数接口中定义的方法来执行lambda表达式,并传入一个参数。

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);
}

上面的代码生成以下结果。


注意

lambda表达式本身不能用作独立的表达式。

lambda表达式的类型由编译器推断。

Java函数式接口定义

函数式接口是具有一个抽象方法的接口。

我们不能使用以下类型的方法来声明一个函数式接口:

  • 默认方法
  • 静态方法
  • 从Object类继承的方法

一个函数式接口可以重新声明Object类中的方法。该方法不被视为抽象方法。因此,我们可以声明lambda表达式使用的另一种方法。

考虑 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接口有两个抽象方法: compare() equals()

equals()方法是Object类中的 equals()方法的重新声明。

@FunctionalInterface注释

@FunctionalInterface 注释在java.lang包中定义。我们可以选择使用它来标记一个函数式接口。

如果注释 @FunctionalInterface 在非函数式接口或其他类型(如类)上注释,则会发生编译时错误。

具有一个抽象方法的接口仍然是一个功能接口,即使我们不用 @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);
}

上面的代码生成以下结果。

通用函数式接口

我们可以使用类型参数与函数式接口来创建通用函数式接口。

以下代码创建具有一个类型参数T的通用函数式参数函数接口。

@FunctionalInterface
public interface  Comparator<T> {
    int compare(T o1, T o2);
}

以下代码使用抽象通用方法定义非通用函数式接口:

@FunctionalInterface
public interface  Processor {
   <T> void  process(T[] list);
}

Java Buildin函数式接口

Java 8在包java.util.function中有函数式接口

函数

表示接受类型T的参数并返回类型R的结果的函数。

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

BiFunction

表示一个函数,它接受类型T和U的两个参数,并返回类型R的结果。

public interface BiFunction<T,U,R>{
   ...
   public R apply(T t, U u);
   ...
}         

谓词

表示为指定参数返回 true false 的布尔函数。

public Predicate<T> {
   ...
   public boolean test(T  t);
   ...
}

BiPredicate

表示为两个指定的参数返回 true false 的布尔函数。

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

Consumer

表示接受参数并且不返回结果的操作。

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

BiConsumer

表示接受两个参数并且不返回结果的操作。

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

Supplier

表示返回类型T的值的函数。

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

UnaryOperator

表示接受参数并返回相同类型的结果的函数。

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

BinaryOperator

表示一个函数,它接受两个参数并返回相同类型的结果。

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

注意2

上述通用buildin函数式接口都是更专用的函数式接口的通用版本。

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

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号