Java ist für immer eine objektorientierte Programmiersprache geblieben. Mit einer objektorientierten Programmiersprache können wir erklären, dass sich alles, was in der Programmiersprache Java vorhanden ist, in den Objekten dreht, mit Ausnahme einiger der primitiven Datentypen und primitiven Methoden aus Gründen der Integrität und Einfachheit. In einer Programmiersprache namens Java gibt es keine einzigen Funktionen. Funktionen in der Programmiersprache Java sind Teil einer Klasse, und wenn jemand sie verwenden möchte, muss er die Klasse oder das Objekt der Klasse verwenden, um eine beliebige Funktion aufzurufen.
Java-Funktionsschnittstellen
A funktionale Schnittstelle ist eine Schnittstelle, die nur eine abstrakte Methode enthält. Sie können nur eine Funktionalität aufweisen. Ab Java 8 Lambda-Ausdrücke kann verwendet werden, um die Instanz einer funktionalen Schnittstelle darzustellen. Eine funktionale Schnittstelle kann eine beliebige Anzahl von Standardmethoden haben. Lauffähig , ActionListener , Und Vergleichbar sind einige Beispiele für funktionale Schnittstellen.
Functional Interface wird zusätzlich erkannt als Schnittstellen für einzelne abstrakte Methoden . Kurz gesagt, sie sind auch bekannt als SAM-Schnittstellen . Funktionale Schnittstellen in Java sind die neue Funktion, die Benutzern den Ansatz einer grundlegenden Programmierung ermöglicht.
Funktionsschnittstellen sind in Java SE 8 mit Lambda-Ausdrücken und Methodenreferenzen enthalten, um den Code lesbarer, sauberer und unkomplizierter zu machen. Funktionale Schnittstellen sind Schnittstellen, die sicherstellen, dass sie genau nur eine abstrakte Methode enthalten. Funktionale Schnittstellen werden verwendet und ausgeführt, indem die Schnittstelle mit einem dargestellt wird Anmerkung aufgerufen @FunctionalInterface . Wie bereits beschrieben, können funktionale Schnittstellen nur eine abstrakte Methode enthalten. Sie können jedoch eine beliebige Anzahl an Standard- und statischen Methoden enthalten.
In funktionalen Schnittstellen ist die Verwendung des Schlüsselworts „abstract“ nicht erforderlich, da die Verwendung des Schlüsselworts „abstract“ optional ist, da die in der Schnittstelle definierte Methode standardmäßig nur abstrakt ist. Wir können Lambda-Ausdrücke auch als Instanz einer funktionalen Schnittstelle bezeichnen.
Beispiel für Java-Funktionsschnittstellen
Beispiel 1:
Vor Java 8 mussten wir anonyme innere Klassenobjekte erstellen oder diese Schnittstellen implementieren.
Java
// 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();> > }> }> |
>
>Ausgabe
New thread created>
Beispiel 2:
Ab Java 8 können wir zuweisen Lambda-Ausdruck zu seinem funktionalen Schnittstellenobjekt wie folgt:
Java
// 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();> > }> }> |
>
>Ausgabe
New thread created>
@FunctionalInterface-Annotation
Die Annotation @FunctionalInterface wird verwendet, um sicherzustellen, dass die funktionale Schnittstelle nicht mehr als eine abstrakte Methode haben kann. Falls mehr als eine abstrakte Methode vorhanden ist, markiert der Compiler die Meldung „Unerwartete @FunctionalInterface-Annotation“. Es ist jedoch nicht zwingend erforderlich, diese Anmerkung zu verwenden.
Chr-Funktion Python
Nachfolgend finden Sie die Umsetzung des oben genannten Themas:
Java
// 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;> > // parameter passed and return type must be> > // same as defined in the prototype> > int> ans = s.calculate(a);> > System.out.println(ans);> > }> }> |
>
>Ausgabe
25>
Einige integrierte Java-Funktionsschnittstellen
Seit Java SE 1.8 gibt es viele Schnittstellen, die in funktionale Schnittstellen umgewandelt werden. Alle diese Schnittstellen sind mit @FunctionalInterface annotiert. Diese Schnittstellen sind wie folgt:
- Runnable –> Diese Schnittstelle enthält nur die run()-Methode. Comparable –> Diese Schnittstelle enthält nur die Methode CompareTo(). ActionListener –> Diese Schnittstelle enthält nur die Methode actionPerformed(). Callable –> Diese Schnittstelle enthält nur die Methode call().
Java SE 8 umfasste vier Hauptarten funktionaler Schnittstellen die in mehreren Situationen angewendet werden kann, wie unten erwähnt:
- Lieferant der Verbraucherprädikatfunktion
Unter den vorherigen vier Schnittstellen verfügen auch die ersten drei Schnittstellen, d. h. Consumer, Predicate und Function, über Ergänzungen, die unten bereitgestellt werden –
- Verbraucher -> Bi-Verbraucher
- Prädikat -> Bi-Prädikat
- Funktion -> Bifunktion, unärer Operator, binärer Operator
1. Verbraucher
Die Verbraucherschnittstelle der funktionalen Schnittstelle ist diejenige, die nur ein Argument oder ein gentrifiziertes Argument akzeptiert. Die Consumer-Schnittstelle hat keinen Rückgabewert. Es gibt nichts zurück. Es gibt auch funktionale Varianten des Consumers – DoubleConsumer, IntConsumer und LongConsumer. Diese Varianten akzeptieren primitive Werte als Argumente.
Neben diesen Varianten gibt es noch eine weitere Variante der Consumer-Schnittstelle, die als Bi-Consumer bekannt ist.
Bi-Verbraucher – Bi-Consumer ist die aufregendste Variante der Consumer-Schnittstelle. Die Consumer-Schnittstelle akzeptiert nur ein Argument, die Bi-Consumer-Schnittstelle hingegen akzeptiert zwei Argumente. Sowohl Consumer als auch Bi-Consumer haben keinen Rückgabewert. Es gibt auch nichts zurück, genau wie die Consumer-Schnittstelle. Es wird beim Durchlaufen der Einträge der Karte verwendet.
Syntax / Prototyp der Consumer Functional Interface –
Consumer consumer = (value) ->System.out.println(value);>
Diese Implementierung der Java Consumer-Funktionsschnittstelle druckt den Wert, der als Parameter an die Druckanweisung übergeben wird. Diese Implementierung verwendet die Lambda-Funktion von Java.
2. Prädikat
In der wissenschaftlichen Logik wird eine Funktion, die ein Argument akzeptiert und im Gegenzug einen booleschen Wert als Antwort generiert, als Prädikat bezeichnet. In ähnlicher Weise ist in der Programmiersprache Java eine Prädikat-Funktionsschnittstelle von Java ein Funktionstyp, der einen einzelnen Wert oder ein einzelnes Argument akzeptiert, diesen verarbeitet und eine boolesche Antwort (Wahr/Falsch) zurückgibt. Die Implementierung der Predicate-Funktionsschnittstelle kapselt auch die Filterlogik (ein Prozess, der zum Filtern von Stream-Komponenten auf der Basis eines bereitgestellten Prädikats verwendet wird) in Java.
Genau wie die Consumer-Funktionsschnittstelle weist auch die Predicate-Funktionsschnittstelle einige Erweiterungen auf. Dies sind IntPredicate, DoublePredicate und LongPredicate. Diese Arten von funktionalen Prädikatschnittstellen akzeptieren nur primitive Datentypen oder Werte als Argumente.
Linux, wie man ein Verzeichnis umbenennt
Bi-Prädikat – Bi-Predicate ist auch eine Erweiterung der Predicate-Funktionsschnittstelle, die statt eines zwei Argumente entgegennimmt, einige Verarbeitungsvorgänge durchführt und den booleschen Wert zurückgibt.
Syntax der Prädikat-Funktionsschnittstelle –
public interface Predicate { boolean test(T t); }>
Die prädikatfunktionale Schnittstelle kann auch über eine Klasse implementiert werden. Die Syntax für die Implementierung der Prädikat-Funktionsschnittstelle mithilfe einer Klasse ist unten angegeben:
public class CheckForNull implements Predicate { @Override public boolean test(Object o) { return o != null; } }>
Die Java-Prädikat-Funktionsschnittstelle kann auch mithilfe von Lambda-Ausdrücken implementiert werden. Nachfolgend finden Sie ein Beispiel für die Implementierung der Predicate-Funktionsschnittstelle:
Predicate predicate = (value) ->Wert != null;>
Diese Implementierung von Funktionsschnittstellen in Java mithilfe von Java-Lambda-Ausdrücken ist überschaubarer und effektiver als die Implementierung mithilfe einer Klasse, da beide Implementierungen die gleiche Arbeit leisten, d. h. die gleiche Ausgabe zurückgeben.
3. Funktion
Eine Funktion ist eine Art funktionale Schnittstelle in Java, die nur ein einziges Argument empfängt und nach der erforderlichen Verarbeitung einen Wert zurückgibt. Es gibt viele Versionen von Funktionsschnittstellen, da ein primitiver Typ kein allgemeines Typargument implizieren kann. Daher benötigen wir diese Versionen von Funktionsschnittstellen. Viele verschiedene Versionen der Funktionsschnittstellen sind instrumentell und werden häufig in primitiven Typen wie double, int, long verwendet. Die unterschiedlichen Sequenzen dieser primitiven Typen werden auch im Argument verwendet.
Diese Versionen sind:
Bi-Funktion
Die Bi-Funktion hängt im Wesentlichen mit einer Funktion zusammen. Außerdem benötigt es zwei Argumente, während Function ein Argument akzeptiert.
Der Prototyp und die Syntax von Bi-Function sind unten angegeben:
@FunctionalInterface public interface BiFunction { R apply(T t, U u); ....... }>
Im obigen Code der Schnittstelle sind T und U die Eingaben, und es gibt nur eine Ausgabe, nämlich R.
Unärer Operator und Binäroperator
Es gibt auch zwei weitere funktionale Schnittstellen mit den Namen Unärer Operator und Binärer Operator. Beide erweitern die Funktion bzw. die Bi-Funktion. Mit einfachen Worten: Der unäre Operator erweitert die Funktion und der binäre Operator erweitert die Bi-Funktion.
Der Prototyp des unären Operators und des binären Operators wird unten erwähnt:
ich. Unärer Operator
@FunctionalInterface public interface UnaryOperator extends Function { ……... }>
ii . Binärer Operator
@FunctionalInterface public interface BinaryOperator extends BiFunction { ……... }>
Anhand des obigen Beispiels können wir verstehen, dass der unäre Operator nur ein Argument akzeptiert und nur ein einziges Argument zurückgibt. Dennoch müssen im unären Operator sowohl die Eingabe- als auch die Ausgabewerte identisch sein und vom gleichen Typ sein.
Andererseits nimmt der Binäroperator zwei Werte an und gibt einen Wert zurück, vergleichbar mit der Bi-Funktion, aber ähnlich wie bei einem Unäroperator müssen die Eingabe- und Ausgabewerttypen identisch sein und vom gleichen Typ sein.
4. Lieferant
Die funktionale Lieferantenschnittstelle ist ebenfalls eine Art funktionaler Schnittstelle, die keine Eingaben oder Argumente entgegennimmt und dennoch eine einzelne Ausgabe zurückgibt. Diese Art von Funktionsschnittstelle wird im Allgemeinen bei der verzögerten Generierung von Werten verwendet. Funktionsschnittstellen des Lieferanten werden auch zur Definition der Logik für die Generierung beliebiger Sequenzen verwendet. Zum Beispiel – Die Logik hinter der Fibonacci-Reihe kann mit Hilfe des Streams generiert werden. Methode generieren, die von der funktionalen Schnittstelle des Lieferanten implementiert wird.
Die verschiedenen Erweiterungen der Lieferantenfunktionsschnittstelle enthalten viele weitere Lieferantenfunktionen wie BooleanSupplier, DoubleSupplier, LongSupplier und IntSupplier. Der Rückgabetyp all dieser weiteren Spezialisierungen sind nur die entsprechenden Grundelemente.
Syntax/Prototyp der Lieferantenfunktionsschnittstelle ist –
@FunctionalInterface public interface Supplier{ // gets a result …………. // returns the specific result ………… T.get(); }>
Nachfolgend finden Sie die Umsetzung des oben genannten Themas:
Java
// 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);> > }> > }> }> |
>
>Ausgabe
Geek GeeksQuiz Geek2>
Wichtige Punkte/Beobachtung ns:
Hier sind einige wichtige Punkte zu funktionalen Schnittstellen in Java:
- In funktionalen Schnittstellen wird nur eine abstrakte Methode unterstützt. Wenn die Annotation einer Funktionsschnittstelle, d. h. @FunctionalInterface, nicht mit einer Funktionsschnittstelle implementiert oder geschrieben wird, können darin mehr als eine abstrakte Methode deklariert werden. In dieser Situation mit mehr als einer Funktion wird diese Schnittstelle jedoch nicht als funktionale Schnittstelle bezeichnet. Man spricht von einer nichtfunktionalen Schnittstelle.
- Für die Annotation @FunctionalInterface besteht keine solche Notwendigkeit, da sie nur freiwillig ist. Dies wurde geschrieben, weil es bei der Überprüfung des Compiler-Levels hilft. Darüber hinaus ist es optional.
- Der Funktionsschnittstelle können unendlich viele Methoden (ob statisch oder standardmäßig) hinzugefügt werden. Mit einfachen Worten: Es gibt keine Begrenzung für eine funktionale Schnittstelle, die statische und Standardmethoden enthält.
- Das Überschreiben von Methoden der übergeordneten Klasse verstößt nicht gegen die Regeln einer funktionalen Schnittstelle in Java.
- Der java.util.function Das Paket enthält viele integrierte Funktionsschnittstellen in Java 8.