blog

Java8の関数型インターフェースについて知らないことがあるかもしれない。

Lambdaはいつ使えますか? 一般的に、Lambda式は関数型インターフェースで使われます。関数型インターフェースはJava 8で導入されました。関数型インターフェースとは、抽象的なメソッドを1つだ...

Sep 23, 2020 · 9 min. read
シェア

Lambdaはどのような場合に使用できますか? 一般的に、Lambda式は関数型インターフェースで使用されます。関数型インターフェースはJava 8で導入されましたが、その説明は簡単です:関数型インターフェースとは、抽象メソッドを1つだけ持ち、抽象でないメソッドを複数持つことができるインターフェースのことです。

I. 構文の定義

/**
* 機能インターフェースの定義
* このインターフェースは@FunctionalInterface  
*/
@FunctionalInterface
public interface ICollectionService {
   /**
    * printメソッドを定義する
    */
   void print();
}

Java 8以前には、以下のように多くの機能的インターフェースが存在していました:

  • java.lang.Runnable
  • java.util.concurrent.Callable
  • java.security.PrivilegedAction
  • java.io.FileFilter
  • java.nio.file.PathMatcher
  • java.lang.reflect.InvocationHandler
  • java.beans.PropertyChangeListener
  • java.awt.event.ActionListener
  • javax.swing.event.ChangeListener

Java8に追加された新しい関数型インターフェースはjava.util.functionパッケージの下にあり、Javaの関数型プログラミングをサポートする多くのクラスが含まれています:

1 **BiConsumer**は、2つの入力パラメーターを受け取り、結果を返さない操作を表します。
2 **BiFunction**は、2つの入力パラメータを受け取り、結果を返すメソッドを表します。
3 **BinaryOperator**は、同じ型の2つの演算子に作用し、演算子と同じ型の結果を返す演算を表します。
4 **BiPredicate**は、2つの引数を持つブール値のメソッドを表します。
5 "BooleanSupplier"は、ブーリアン結果の提供者を表します。
6 **Consumer**は、入力パラメータを受け取り、何も返さない操作を表します。
7 "DoubleBinaryOperator"は、2つの2倍値の演算子に作用し、2倍値の結果を返す演算を表します。
8 DoubleConsumer"は、double 値のパラメータを受け入れ、結果を返さない操作を表します。
9 **DoubleFunction**は、二重値の引数を取り、結果を返すメソッドを表します。
10 "DoublePredicate"は、二重値の引数を持つブール値のメソッドを表します。
11 "DoubleSupplier"は、二重値構造の提供者を表します。
12 DoubleToIntFunction"は double 型の入力を受け付け、int 型の結果を返します。
13 DoubleToLongFunction"は double 型の入力を受け付け、long 型の結果を返します。
14
15 **関数**は入力パラメータを取り、結果を返します。
16 "IntBinaryOperator"は、同じint型の2つのパラメータを受け入れ、戻り値の型もint型です。
17 "IntConsumer"は、int型の入力パラメータを1つ受け取り、戻り値は受け取りません。
18 **IntFunction**は、int型の入力パラメータを受け取り、結果を返します。
19 "IntPredicate":int型の入力パラメータを受け取り、boolean型の結果を返します。
20 "IntSupplier"はパラメータを持たず、int型の結果を返します。
21 "IntToDoubleFunction"はint型の入力を受け付け、double型の結果を返します。
22 "IntToLongFunction"はint型の入力を受け付け、long型の結果を返します。
23 "IntUnaryOperator"は、同じint型のパラメータを1つ受け取り、戻り値の型もint型です。
24 "LongBinaryOperator"は、long型の2つのパラメータを受け付け、戻り値もlong型です。
25 "LongConsumer"は、long型の入力パラメータを1つ受け付けます。
26 **LongFunction**はlong型の入力パラメータを取り、結果を返します。
27 "LongPredicate"Rは、long型の入力パラメータを受け取り、boolean型の結果を返します。
28 "LongSupplier"はパラメータを持たず、結果のlong型の値を返します。
29 "LongToDoubleFunction"はlong入力を受け付け、double結果を返します。
30 "LongToIntFunction"はlong型の入力を受け付け、int型の結果を返します。
31 "LongUnaryOperator"は、同じlong型のパラメータを1つ受け取り、戻り値の型もlong型です。
32 **ObjDoubleConsumer**は、返り値を持たない、object型とdouble型の1つの入力パラメータを受け付けます。
33 **ObjIntConsumer**は、object型の入力パラメータを1つ、戻り値のないint型の入力パラメータを1つ受け入れます。
34 **ObjLongConsumer**は、object型とlong型の1つの入力パラメータを受け付けます。
35 **述語**は入力パラメータを取り、ブール値の結果を返します。
36 **Supplier**はパラメータを持たず、結果を返します。
37 **ToDoubleBiFunction**は、2つの入力パラメータを受け取り、double型の結果を返します。
38 **ToDoubleFunction**は、入力パラメータを受け取り、double型の結果を返します。
39 **ToIntBiFunction**は2つの入力パラメータを受け取り、int型の結果を返します。
40 **ToIntFunction**は、入力パラメータを受け取り、int型の結果を返します。
41 **ToLongBiFunction**は2つの入力パラメータを取り、long型の結果を返します。
42 **ToLongFunction**は入力パラメータを取り、long型の結果を返します。
43 **UnaryOperator**はT型のパラメータを受け入れ、戻り値もT型です。

上部を左に指をスライドさせると全体が表示されます。

Java8では非常に多くの関数型インターフェースが提供されていますが、開発でよく使われる関数型インターフェースは、述語、消費者、関数の3つです。

II.機能的インターフェースの例

述語

java.util.function.Predicateインターフェイスは、一般的なTオブジェクトを受け入れ、ブール値を返すtestと呼ばれる抽象メソッドを定義しています。このインターフェイスは、T型を含むブール式を表現する必要がある場合に使用できます。

"述語インターフェイスを使用した文字列のヌル化".

@FunctionalInterface
public interface Predicate<T> {
   /**
    * Evaluates this predicate on the given argument.
    *
    * @param t the input argument
    * @return {@code true} if the input argument matches the predicate,
    * otherwise {@code false}
    */
   boolean test(T t);
  ...
}
public static void main(String[] args) {
   /**
     * 借助Lambda 表达式实现Predicate test方法
  */
   Predicate<String> p01=(str)->str.isEmpty()||str.trim().isEmpty();
   /**
    * 入力された文字列が空かどうかをテストする
     */
   System.out.println(p01.test(""));
   System.out.println(p01.test(" "));
   System.out.println(p01.test("admin"));
}

テスト結果

Supplier

java.util.function.Consumerインタフェースは、acceptと呼ばれる抽象メソッドを定義しています。T型のオブジェクトにアクセスして何らかの操作を行う必要がある場合、このインターフェイスを使用することができます。

"Consumerを使ったコレクションのトラバーサル操作の実装"

@FunctionalInterface
public interface Consumer<T> {
   /**
    * Performs this operation on the given argument.
    *
    * @param t the input argument
    */
   void accept(T t);
  ...
}
/**
* 借助Lambda表达式实现Consumer accept方法
*/
Consumer<Collection> c01 = (collection) -> {
 if (null != collection && collection.size() > 0) {
  for (Object c : collection) {
   System.out.println(c);
  }
 }
};
List<String> list = new ArrayList<String>();
list.add("Supplier")を実装する。;
list.add("曹操");
list.add("関羽");
// 遍历list 输出元素内容到控制台
c01.accept(list);

機能

java.util.function.Function インターフェイスはapplyと呼ばれるメソッドを定義しており、これは汎用型Tのオブジェクトを受け取り、汎用型Rのオブジェクトを返します。入力を出力にマッピングするラムダを定義する必要がある場合、関数型インタフェースと呼ばれるこのインタフェースを使うことができます。

「Functionを使用したユーザーパスワードのBase64暗号化」。

@FunctionalInterface public interface Function<T, R> {    /**     * Applies this function to the given argument.     *     * @param t the function argument     * @return the function result     */    R apply(T t); } // 实现用户密码 Base64加密操作 Function<String,String> f01=(password)->Base64.getEncoder().encodeToString(password.getBytes()); // 暗号化された文字列を出力する System.out.println(f01.apply(""));

暗号化後の結果は以下の通り:

Supplier

java.util.function.Supplierインターフェイスは、引数を取らず、汎用型Tのオブジェクトを返すgetの抽象メソッドを定義しています。

「SessionFactoryを実装するためにSupplierを使用して作成します。

@FunctionalInterface
public interface Supplier<T> {
   /**
    * Gets a result.
    *
    * @return a result
    */
   T get();
}
/**
* セッションファクトリーオブジェクトを生成する
*/
Supplier<SessionFactory> s = () -> {
   return new SessionFactory();
};
s.get().info();
Read next

暗号技術 - 非対称暗号化

この関数は、ランダムデータ生成器 random を用いて、指定されたワードビット数の RSA 鍵のペアを生成します。 公開鍵は、x509 を介して PKIX 形式の DER エンコーディングにシリアライズされます。

Sep 23, 2020 · 16 min read