はじめに
久しぶりにJavaに触れたら、Consumer<T>とSupplier<T>が分からなかったため、復習を兼ねて本稿にまとめます。
要約
- ConsumerやSupplierは関数型インターフェース
- 関数型インターフェース:abstractメソッドが1つだけ含まれているインターフェース
- Consumerインターフェース:引数を受け取ってその引数を使った処理を実行する
- Supplierインターフェース:引数を受け取らずに値を戻す
- ほかにも様々な関数型インターフェースがある
関数型インターフェースとは
Javaの公式ドキュメントでは以下のように記載されています。
A functional interface is an interface that is not declared sealed and has just one abstract method (aside from the methods of Object), and thus represents a single function contract.
This "single" method may take the form of multiple abstract methods with override-equivalent signatures inherited from superinterfaces; in this case, the inherited methods logically represent a single method.
DeepLに翻訳してもらった結果がこちらです。
関数型インターフェイスとは、(Objectのメソッドは別として)1つの抽象メソッドのみを持ち、sealed宣言されていないインターフェイスのことで、1つの関数契約を表します。
この "単一の "メソッドは、スーパーインターフェースから継承されたオーバーライドと同等のシグネチャを持つ複数の抽象メソッドの形をとることができます。
つまり、Functional Interface(関数型インターフェース)とは1つの抽象メソッドのみを持つインターフェースとなります。
また、sealed
宣言の説明は割愛しますが、以下の記事が個人的にわかりやすかったです。
Consumerインターフェースとは
公式のJavaDocには以下のように記載されています。
単一の入力引数を受け取って結果を返さないオペレーションを表します。Consumerは他のほとんどの関数型インタフェースと異なり、副作用を介して動作することを期待されます。
つまり、Consumerインターフェースは引数を受け取ってその引数を使った処理を実行するメソッドを定めていると言えます。
その定められたメソッドがaccept(T t)
です。
また、副作用とは、Wikipediaによると以下のように記載されています。
式は、評価値を得ること(※関数では「引数を受け取り値を返す」と表現する)が主たる作用とされ、それ以外のコンピュータの論理的状態(ローカル環境以外の状態変数の値)を変化させる作用を副作用という。
副作用の例としては、グローバル変数や静的ローカル変数の変更、ファイルの読み書きなどのI/O実行、などがある。
そのため、コンソールに結果を出力したり、インスタンス変数の値を変える等の処理をConsumerインターフェースのaccept(T t)
メソッドに記載して使用します。
Supplierインターフェースとは
公式のJavaDocには以下のように記載されています
結果のサプライヤを表します。
サプライヤを呼び出すたびに新しい(異なる)結果が返される必要はありません。
なるほどわからん。
わからないなぁと思っていたら以下のような記事を発見しました。
ここには以下のように記載されていました。
名前の通り、Supplerは引数を受け取らずに値を戻す関数型インターフェースです。
get()メソッドを持っています。
使用シーンに関しては、同記事に以下のように記載されていました。
引数を受け取らずに値を戻す時に使います。
具体的にはインスタンスを生成する時や、引数関係なく値を出力する時に利用します。
個人的にはあまり使用頻度は高くなさそうに感じました。(もし「実際にこういうシーンで使用しているよ!」みたいなのがあればコメントお願いします )
他の関数型インターフェース
関数型インターフェースが存在するパッケージ(java.util.function
)には、今回取り上げた関数型インターフェースの他にも多くの種類のインターフェースが存在するっぽいです。
他にも気になったのあれば勉強してまた記事にしてみようと思います。