Java の BiFunction インターフェイス

Mohammad Irfan 2023年10月12日
  1. Java での BiFunction apply() メソッドの例
  2. Java の BiFunction andThen() メソッド
  3. BiFunction インターフェイスで NullPointerException を回避する
  4. Java での HashMap を使用した BiFunction
  5. BiFunction とメソッドリファレンス
  6. まとめ
Java の BiFunction インターフェイス

このチュートリアルでは、Java の BiFunction インターフェイスについて説明します。

BiFunction インターフェースは、Java 8 で導入された組み込みの機能インターフェースであり、java.util.function パッケージに含まれています。2つのジェネリック(1つの引数型と 1つの戻り型)をとる Function インターフェースとは異なり、BiFunction は 2つの引数を取り、結果を生成します。

2つの引数を取り、結果を BiFunction 型のオブジェクトに返すラムダ式またはメソッド参照を割り当てることができます。

BiFunction は、TU、および R の 3つのジェネリックを取ります。TU は、それぞれ 1 番目と 2 番目の引数のタイプです。R は、関数の結果のタイプです。

interface BiFunction<T, U, R>

BiFunction インターフェースには 2つのメソッドがあります。

  • apply():引数に対して定義された操作を実行し、結果を返します。このメソッドの構文は次のとおりです。
R apply(T t, U u) // R is the return type. T and U are the types of the two arguments
  • andThen():合成された関数からの結果を返します。簡単に言うと、最初に 2つの引数に対して BiFunction を実行し、結果を生成します。次に、結果を関数に渡します。このメソッドの構文は次のとおりです。
default<V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after)

Java での BiFunction apply() メソッドの例

Integer 型と Double 型の引数を取り、String を返す単純な BiFunction を作成しましょう。apply() メソッドを使用して引数を渡し、結果を取得しました。

以下の例を参照してください。

import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    // BiFunction with arguments of type Integer and Double
    // and return type of String
    BiFunction<Integer, Double, String> biFunction = (a, b) -> {
      double result = a * b;
      String s = "The result from the BiFunction is: " + result;
      return s;
    };

    String output = biFunction.apply(10, 15.5);
    System.out.print(output);
  }
}

出力:

The result from the BiFunction is: 155.0

Java の BiFunction andThen() メソッド

上で定義した BiFunction の結果を関数に渡しましょう。andThen() メソッドを使用します。このメソッドは、最初に BiFunction の結果を評価し、次にその結果を after 関数に渡します。

import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    // BiFunction with arguments of type Integer and Double
    // and return type of String
    BiFunction<Integer, Double, String> biFunction = (a, b) -> {
      double result = a * b;
      String s = "The result from the BiFunction is: " + result;
      return s;
    };

    // Function with argument of type String
    // and return type of Integer
    Function<String, Integer> after = s -> {
      Integer length = s.length();
      return length;
    };

    int output = biFunction.andThen(after).apply(
        10, 15.5); // first evaluates the BiFunction and then the Function
    System.out.print(output);
  }
}

出力:

40

BiFunction インターフェイスで NullPointerException を回避する

andThen() メソッドに null 参照を渡すと、コードは NullPointerException を返します。以下の例を参照してください。このような間違いを避け、常にコードを try-catch ブロックに配置する必要があります。

import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    BiFunction<Integer, Double, String> biFunction = (a, b) -> {
      double result = a * b;
      String s = "The result from the BiFunction is: " + result;
      return s;
    };

    Function<String, Integer> after = null;

    int output = biFunction.andThen(after).apply(10, 15.5);
    System.out.print(output);
  }
}

出力:

Exception in thread "main" java.lang.NullPointerException
	at java.base/java.util.Objects.requireNonNull(Objects.java:222)
	at java.base/java.util.function.BiFunction.andThen(BiFunction.java:69)
	at SimpleTesting.main(SimpleTesting.java:15)

andThen() メソッドを使用して 2つの BiFunction を統合することはできないことに注意してください。

Java での HashMap を使用した BiFunction

BiFunctions は、compute()computeIfPresent()merge()replaceAll() などのいくつかの HashMap メソッドで引数として使用されます。

HashMap で BiFunction を使用する例を作成しましょう。学生のロール番号とそのスコアを格納する HashMap について考えてみます。ロール番号 101 を除いて、すべての生徒のスコアに 5 を追加する必要があります。

import java.util.HashMap;
import java.util.function.*;

public class SimpleTesting {
  public static void main(String args[]) {
    HashMap<Integer, Double> scoreMap = new HashMap<>();
    scoreMap.put(101, 95.2);
    scoreMap.put(102, 86.0);
    scoreMap.put(103, 91.9);
    scoreMap.put(104, 72.8);
    scoreMap.put(105, 89.5);

    System.out.println("Intial HashMap: " + scoreMap);

    // BiFunction with arguments of type Integer and Double
    // and return type of Double
    BiFunction<Integer, Double, Double> biFunction = (key, value) -> {
      if (key == 101)
        return value;
      else
        return value + 5;
    };
    scoreMap.replaceAll(biFunction);
    System.out.print("HashMap After The Update: " + scoreMap);
  }
}

出力:

Intial HashMap: {101=95.2, 102=86.0, 103=91.9, 104=72.8, 105=89.5}
HashMap After The Update: {101=95.2, 102=91.0, 103=96.9, 104=77.8, 105=94.5}

BiFunction とメソッドリファレンス

これまで、ラムダ式のリファレンスとして BiFunction インターフェースを使用してきました。BiFunction を使用してメソッドを参照することもできます。メソッドは 2つの引数のみを取り、結果を返す必要があります。

与えられた 2つの整数の合計が偶数であるかどうかをチェックする単純な静的メソッドを書いてみましょう。このメソッド参照を BiFunction に割り当てることができます。以下の例を参照してください。

import java.util.function.*;

public class SimpleTesting {
  static boolean isSumEven(int a, int b) {
    int sum = a + b;
    if (sum % 2 == 0)
      return true;
    else
      return false;
  }

  public static void main(String args[]) {
    BiFunction<Integer, Integer, Boolean> biFunction = SimpleTesting::isSumEven;

    System.out.println("Is sum of 10 and 21 even? " + biFunction.apply(10, 21));
    System.out.print("Is sum of 5 and 7 even? " + biFunction.apply(5, 7));
  }
}

出力:

Is sum of 10 and 21 even? false
Is sum of 5 and 7 even? true

まとめ

Java BiFunction インターフェースは機能インターフェースです。ラムダ式またはメソッド参照の割り当てターゲットとして使用されます。2つの引数を渡す必要がある場合は、Function インターフェイスよりも BiFunction インターフェイスの方が優先されます。

BiFunction インターフェースには、apply()andThen() の 2つのメソッドが含まれています。apply() メソッドは、指定された 2つの引数に関数を適用します。andThen() メソッドは、BiFunction の結果を Function インターフェイスに渡すために使用されます。

関連記事 - Java Stream

関連記事 - Java Interface