Java の関数インターフェース

Java は永遠にオブジェクト指向プログラミング言語であり続けます。オブジェクト指向プログラミング言語を使用すると、完全性と単純性を目的とした一部のプリミティブ データ型とプリミティブ メソッドを除き、Java プログラミング言語に存在するすべてがオブジェクト全体で回転すると宣言できます。 Java と呼ばれるプログラミング言語には単独の関数は存在しません。 Java プログラミング言語の関数はクラスの一部であり、それらを使用したい場合は、クラスまたはクラスのオブジェクトを使用して関数を呼び出す必要があります。

Java 関数インターフェイス

機能インターフェイス は、抽象メソッドを 1 つだけ含むインターフェイスです。表示できる機能は 1 つだけです。 Java 8以降では、 ラムダ式 関数インターフェイスのインスタンスを表すために使用できます。関数インターフェイスには、任意の数のデフォルト メソッドを含めることができます。 実行可能 アクションリスナー そして 匹敵します は、機能インターフェイスの例の一部です。

関数インターフェースはさらに次のように認識されます。 単一の抽象メソッドのインターフェイス 。簡単に言うと、それらは次のようにも知られています。 SAMインターフェース 。 Java の関数型インターフェイスは、ユーザーに基本的なプログラミングのアプローチを提供する新しい機能です。

Java SE 8 には、コードをより読みやすく、クリーンで、単純なものにするために、ラムダ式とメソッド参照を備えた関数インターフェイスが組み込まれています。関数型インターフェイスは、抽象メソッドが 1 つだけ含まれることを保証するインターフェイスです。関数型インターフェイスは、インターフェイスを次のように表すことによって使用および実行されます。 と呼ばれる注釈 @FunctionalInterface 。前述したように、関数型インターフェイスには抽象メソッドを 1 つだけ含めることができます。ただし、デフォルトおよび静的メソッドを任意の量だけ含めることができます。

Functional インターフェイスでは、インターフェイス内で定義されたメソッドはデフォルトで抽象のみであるため、abstract キーワードの使用はオプションであるため、abstract キーワードを使用する必要はありません。ラムダ式を関数インターフェイスのインスタンスとして呼び出すこともできます。

Java 関数インターフェイスの例

例 1:

Java 8 より前では、匿名の内部クラス オブジェクトを作成するか、これらのインターフェイスを実装する必要がありました。

ジャワ




// Java program to demonstrate functional interface> class> Test {> > public> static> void> main(String args[])> > {> > // create anonymous inner class object> > new> Thread(> new> Runnable() {> > @Override> public> void> run()> > {> > System.out.println(> 'New thread created'> );> > }> > }).start();> > }> }>

出力

New thread created 

例 2:

Java 8 以降では、次のように割り当てることができます。 ラムダ式 次のように関数インターフェイス オブジェクトに追加します。

ジャワ




// Java program to demonstrate Implementation of> // functional interface using lambda expressions> class> Test {> > public> static> void> main(String args[])> > {> > // lambda expression to create the object> > new> Thread(() ->{> > System.out.println(> 'New thread created'> );> > }).start();> > }> }>

出力

New thread created 

@FunctionalInterface アノテーション

@FunctionalInterface アノテーションは、関数型インターフェースが複数の抽象メソッドを持つことができないようにするために使用されます。複数の抽象メソッドが存在する場合、コンパイラは「予期しない @FunctionalInterface アノテーション」メッセージにフラグを立てます。ただし、このアノテーションの使用は必須ではありません。

以下は、上記のトピックの実装です。

ジャワ




// Java program to demonstrate lambda expressions to> // implement a user defined functional interface.> @FunctionalInterface> interface> Square {> > int> calculate(> int> x);> }> class> Test {> > public> static> void> main(String args[])> > {> > int> a => 5> ;> > // lambda expression to define the calculate method> > Square s = (> int> x) ->x * x;>>'

出力

25 

いくつかの組み込み Java 関数インターフェイス

Java SE 1.8 以降、関数型インターフェースに変換されたインターフェースが多数あります。これらすべてのインターフェイスには @FunctionalInterface の注釈が付けられます。これらのインターフェースは次のとおりです。

    Runnable –> このインターフェイスには run() メソッドのみが含まれています。 Comparable –> このインターフェイスには、compareTo() メソッドのみが含まれています。 ActionListener –> このインターフェイスには、actionPerformed() メソッドのみが含まれています。 Callable –> このインターフェイスには call() メソッドのみが含まれます。

Java SE 8には、主に4種類の関数インターフェースが含まれていました これは、以下に示すように、複数の状況に適用できます。

    コンシューマー述語関数サプライヤー

前の 4 つのインターフェイスのうち、最初の 3 つのインターフェイス (Consumer、Predicate、および Function) にも同様に以下の追加機能があります。

  1. コンシューマー -> バイコンシューマー
  2. 述語 -> 二重述語
  3. 関数 -> 二関数、単項演算子、二項演算子

1. 消費者

関数型インターフェイスのコンシューマ インターフェイスは、引数を 1 つだけ受け入れるか、ジェントリファイドされた引数を受け入れます。コンシューマ インターフェイスには戻り値がありません。何も返しません。 Consumer の機能バリアントとして DoubleConsumer、IntConsumer、LongConsumer もあります。これらのバリアントは、引数としてプリミティブ値を受け入れます。

これらのバリアントの他に、Bi-Consumer として知られる Consumer インターフェイスのバリアントがもう 1 つあります。

バイコンシューマー – Bi-Consumer は、Consumer インターフェースの最もエキサイティングなバリエーションです。コンシューマ インターフェイスは引数を 1 つだけ受け取りますが、一方、バイコンシューマ インターフェイスは 2 つの引数を受け取ります。 Consumer と Bi-Consumer の両方に戻り値はありません。また、Consumer インターフェイスと同様に何も返しません。これは、マップのエントリを反復処理する際に使用されます。

コンシューマ機能インターフェイスの構文/プロトタイプ –

Consumer consumer = (value) ->System.out.println(値);> 

Java Consumer 関数インターフェイスのこの実装は、print ステートメントにパラメータとして渡された値を出力します。この実装ではJavaのLambda関数を使用します。

2. 述語

科学論理では、引数を受け入れ、その代わりに答えとしてブール値を生成する関数は述語として知られています。同様に、Java プログラミング言語では、Java の述語関数インターフェイスは、単一の値または引数を受け入れ、それに何らかの処理を実行し、ブール値 (True/False) の答えを返す関数のタイプです。 Predicate 関数インターフェイスの実装は、Java でのフィルタリングのロジック (提供された述語に基づいてストリーム コンポーネントをフィルタリングするために使用されるプロセス) もカプセル化します。

Consumer 関数インターフェースと同様に、Predicate 関数インターフェースにもいくつかの拡張機能があります。これらは、IntPredicate、DoublePredicate、および LongPredicate です。これらのタイプの述語関数インターフェイスは、プリミティブ データ型または値のみを引数として受け入れます。

二重述語 – Bi-Predicate は、Predicate 関数インターフェイスの拡張でもあり、引数を 1 つではなく 2 つ取り、何らかの処理を行ってブール値を返します。

述語関数インターフェイスの構文 –

public interface Predicate { boolean test(T t); } 

述語関数インターフェイスは、クラスを使用して実装することもできます。クラスを使用した述語関数インターフェイスの実装の構文は次のとおりです。

public class CheckForNull implements Predicate { @Override public boolean test(Object o) { return o != null; } } 

Java 述語関数インターフェイスは、Lambda 式を使用して実装することもできます。 Predicate 関数インターフェイスの実装例を以下に示します。

Predicate predicate = (value) ->値 != null;>>'   

Java Lambda 式を使用した Java での関数インターフェイスのこの実装は、クラスを使用して実装されたものよりも管理しやすく、効果的です。これは、両方の実装が同じ作業を行う、つまり同じ出力を返すためです。

3. 機能

関数は Java の関数インターフェイスの一種で、引数を 1 つだけ受け取り、必要な処理の後に値を返します。プリミティブ型は一般的な型引数を暗示できないため、関数インターフェイスには多くのバージョンがあり、これらのバージョンの関数インターフェイスが必要です。関数インターフェイスの多くの異なるバージョンが実用的であり、double、int、long などのプリミティブ型でよく使用されます。これらのプリミティブ型のさまざまなシーケンスも引数で使用されます。

これらのバージョンは次のとおりです。

二機能

Bi-Function は実質的に Function に関連しています。さらに、Function は 2 つの引数を受け取りますが、Function は 1 つの引数を受け取ります。

Bi-Function のプロトタイプと構文を以下に示します。




// A simple program to demonstrate the use> // of predicate interface> import> java.util.*;> import> java.util.function.Predicate;> class> Test {> > public> static> void> main(String args[])> > {> > // create a list of strings> > List names = Arrays.asList(> > 'Geek'> ,> 'GeeksQuiz'> ,> 'g1'> ,> 'QA'> ,> 'Geek2'> );> > // declare the predicate type as string and use> > // lambda expression to create object> > Predicate p = (s) ->s.startsWith(>> 'G'> );> > // Iterate through the list> > for> (String st : names) {> > // call the test method> > if> (p.test(st))> > System.out.println(st);> > }> > }> }>

出力

Geek GeeksQuiz Geek2 

注意事項・観察事項 ns:

Java の関数型インターフェイスに関する重要な点をいくつか示します。

  1. 関数型インターフェイスでは、サポートされる抽象メソッドは 1 つだけです。関数インターフェイスのアノテーション、つまり @FunctionalInterface が実装されていない場合、または関数インターフェイスを使用して記述されていない場合は、その中で複数の抽象メソッドを宣言できます。ただし、複数の関数があるこの状況では、そのインターフェイスは関数インターフェイスとは呼ばれません。これは非機能インターフェイスと呼ばれます。
  2. @FunctionalInterface アノテーションは任意のみであるため、そのような必要はありません。これは、コンパイラのレベルを確認するのに役立つために書かれています。これ以外はオプションです。
  3. 関数インターフェイスには、無限の数のメソッド (静的かデフォルトかに関係なく) を追加できます。簡単に言うと、静的メソッドとデフォルト メソッドを含む関数インターフェイスには制限がありません。
  4. 親クラスからメソッドをオーバーライドすることは、Java の関数インターフェイスの規則に違反しません。
  5. java.util.function パッケージには、Java 8 の組み込み関数インターフェイスが多数含まれています。