it-swarm.com.de

Was ist die Verwendung von Functional Interface in Java 8?

Ich bin auf einen neuen Begriff namens Functional Interface in Java 8 gestoßen.

Ich konnte nur eine Verwendung dieser Schnittstelle finden, während ich mit Lambda-Ausdrücken arbeitete.

Java 8 bietet einige eingebaute funktionale Schnittstellen. Wenn wir eine funktionale Schnittstelle definieren möchten, können wir das @FunctionalInterface Anmerkung. Es wird uns erlauben, nur eine einzige Methode in der Schnittstelle zu deklarieren.

Zum Beispiel:

@FunctionalInterface
interface MathOperation {
    int operation(int a, int b);
}

Wie nützlich ist es in Java 8, außer nur mit Lambda-Ausdrücken zu arbeiten?

Die Frage hier unterscheidet sich von der, die ich gestellt habe. Es wird gefragt, warum wir Functional Interface benötigen, wenn wir mit dem Lambda-Ausdruck arbeiten. Meine Frage ist: Warum verwenden Functional Interface nicht direkt mit Lambda-Ausdrücken?

137
Madhusudan

Die Annotation @FunctionalInterface Ist nützlich, um die Kompilierungszeit Ihres Codes zu überprüfen. Sie können nicht mehr als eine Methode außer static, default und abstrakten Methoden haben, die Methoden in Object in Ihrem @FunctionalInterface Oder einer anderen als Funktion verwendeten Schnittstelle überschreiben Schnittstelle.

Sie können Lambdas jedoch auch ohne diese Annotation verwenden und Methoden ohne die Annotation @Override Überschreiben.

Aus Dokumenten

eine funktionale Schnittstelle hat genau eine abstrakte Methode. Da Standardmethoden eine Implementierung haben, sind sie nicht abstrakt. Wenn eine Schnittstelle deklariert, dass eine abstrakte Methode eine der öffentlichen Methoden von Java.lang.Object überschreibt, wird dies auch nicht für die Anzahl der abstrakten Methoden der Schnittstelle berücksichtigt, da für jede Implementierung der Schnittstelle eine Implementierung von Java.lang.Object oder einer anderen Instanz verwendet wird

Dies kann verwendet werden im Lambda-Ausdruck:

public interface Foo {
  public void doSomething();
}

Dies kann nicht verwendet werden im Lambda-Ausdruck:

public interface Foo {
  public void doSomething();
  public void doSomethingElse();
}

Dies gibt aber Kompilierungsfehler:

@FunctionalInterface
public interface Foo {
  public void doSomething();
  public void doSomethingElse();
}

Ungültige Anmerkung '@FunctionalInterface'; Foo ist keine funktionale Schnittstelle

120
Sergii Bishyr

Das Dokumentation unterscheidet in der Tat den Zweck

Ein informativer Annotationstyp, der angibt, dass eine Schnittstellentypdeklaration eine funktionale Schnittstelle im Sinne von Java) sein soll = Sprachspezifikation.

und der Anwendungsfall

Beachten Sie, dass Instanzen von Funktionsschnittstellen mit Lambda-Ausdrücken, Methodenreferenzen oder Konstruktorreferenzen erstellt werden können.

deren Formulierung andere Anwendungsfälle im Allgemeinen nicht ausschließt. Da der Hauptzweck darin besteht, eine Funktionsschnittstelle anzugeben, läuft Ihre eigentliche Frage auf „Gibt es andere Anwendungsfälle? für funktionale Schnittstellen außer Lambda-Ausdrücken und Methoden-/Konstruktorreferenzen? ”

Da Funktionsschnittstelle ist ein Java Sprachkonstrukt definiert durch die Java Sprachspezifikation) , nur diese Spezifikation kann diese Frage beantworten:

JLS §9.8. Functional Interfaces :

Zusätzlich zum üblichen Verfahren zum Erstellen einer Schnittstelleninstanz durch Deklarieren und Instanziieren einer Klasse (§15.9) können Instanzen funktionaler Schnittstellen mit Methodenreferenzausdrücken und Lambda-Ausdrücken (§15.13, §15.27) erstellt werden.

Die Java Language Specification sagt also nichts anderes aus, der einzige in diesem Abschnitt erwähnte Anwendungsfall ist das Erstellen von Schnittstelleninstanzen mit Methodenreferenzausdrücken und Lambda-Ausdrücken. (Dies schließt Konstruktorreferenzen so ein, wie sie sind als eine Form des Methodenreferenzausdrucks in der Beschreibung vermerkt).

In einem Satz gibt es also keinen anderen Anwendungsfall für Java 8.

12
Holger

Überhaupt nicht. Lambda-Ausdrücke sind der einzige Punkt dieser Anmerkung.

10
Louis Wasserman

Wie andere gesagt haben, ist eine funktionale Schnittstelle eine Schnittstelle, die eine Methode verfügbar macht. Es kann mehr als eine Methode geben, aber alle anderen müssen eine Standardimplementierung haben. Der Grund, warum es als "funktionale Schnittstelle" bezeichnet wird, liegt darin, dass es effektiv als Funktion fungiert. Da Sie Schnittstellen als Parameter übergeben können, sind Funktionen jetzt "erstklassige Bürger" wie in funktionalen Programmiersprachen. Dies hat viele Vorteile, die sich bei Verwendung der Stream-API deutlich bemerkbar machen. Natürlich sind Lambda-Ausdrücke die offensichtlichste Verwendung für sie.

9
Sina Madani

Ein Lambda-Ausdruck kann einem funktionalen Schnittstellentyp zugewiesen werden, Methodenreferenzen ebenso wie anonyme Klassen.

Eine nette Sache über die spezifischen Funktionsschnittstellen in Java.util.function ist, dass sie zusammengesetzt werden können, um neue Funktionen zu erstellen (wie Function.andThen und Function.compose, Predicate.and, etc.) aufgrund der darin enthaltenen praktischen Standardmethoden.

5
Hank D

Eine Schnittstelle mit nur einer abstrakten Methode heißt Functional Interface. Es ist nicht obligatorisch, @FunctionalInterface zu verwenden, es wird jedoch empfohlen, es mit funktionalen Schnittstellen zu verwenden, um das versehentliche Hinzufügen zusätzlicher Methoden zu vermeiden. Wenn die Schnittstelle mit der Anmerkung @FunctionalInterface versehen ist und mehr als eine abstrakte Methode verwendet wird, wird ein Compilerfehler ausgegeben.

package com.akhi;
    @FunctionalInterface
    public interface FucnctionalDemo {

      void letsDoSomething();
      //void letsGo();      //invalid because another abstract method does not allow
      public String toString();    // valid because toString from Object 
      public boolean equals(Object o); //valid

      public static int sum(int a,int b)   // valid because method static
        {   
            return a+b;
        }
        public default int sub(int a,int b)   //valid because method default
        {
            return a-b;
        }
    }
4
Akhilesh

Sie können Lambda in Java 8

public static void main(String[] args) {
    tentimes(inputPrm - > System.out.println(inputPrm));
    //tentimes(System.out::println);  // You can also replace lambda with static method reference
}

public static void tentimes(Consumer myFunction) {
    for (int i = 0; i < 10; i++)
        myFunction.accept("hello");
}

Weitere Informationen zu Java Lambdas und FunctionalInterfaces

2
Websterix

@FunctionalInterface ist eine neue Annotation, die mit Java 8) veröffentlicht wurde und Zieltypen für Lambda-Ausdrücke bereitstellt. Sie wird zur Überprüfung der Kompilierungszeit Ihres Codes verwendet.

Wenn du es benutzen willst:

1- Ihre Schnittstelle darf nicht mehr als eine abstrakte Methode haben, sonst wird ein Kompilierungsfehler angezeigt.

1- Ihre Schnittstelle Sollte pure sein, was bedeutet, dass die funktionale Schnittstelle von statusfreien Klassen implementiert werden soll. Ein Beispiel für pure ist Comparator interface, da es nicht vom Status des Implementierers abhängt case No Kompilierungsfehler werden ausgegeben, aber in vielen Fällen können Sie Lambda nicht mit dieser Art von Schnittstellen verwenden

Das Java.util.function Paket enthält verschiedene allgemeine Funktionsschnittstellen wie Predicate, Consumer, Function und Supplier.

Beachten Sie auch, dass Sie Lambdas ohne diese Anmerkung verwenden können.

2
Ahmad Al-Kurdi

Neben anderen Antworten, denke ich, kann der Hauptgrund für "warum die Verwendung von Functional Interface anders als direkt mit Lambda-Ausdrücken" mit der Natur von Java Sprache, die objektorientiert ist) zusammenhängen.

Die Hauptattribute von Lambda-Ausdrücken sind: 1. Sie können weitergegeben werden. 2. Sie können in Zukunft zu einer bestimmten Zeit (mehrmals) ausgeführt werden. Um diese Funktion nun in Sprachen zu unterstützen, behandeln einige andere Sprachen einfach diese Angelegenheit.

Zum Beispiel kann in Java Script) eine Funktion (anonyme Funktion oder Funktionsliterale) als Objekt angesprochen werden, so dass Sie diese einfach erstellen und auch einer Variablen zuordnen können und so Zum Beispiel:

var myFunction = function (...) {
    ...;
}
alert(myFunction(...));

oder über ES6 können Sie eine Pfeilfunktion verwenden.

const myFunction = ... => ...

Bisher haben Java Sprachentwickler nicht akzeptiert, auf diese Weise mit den genannten Funktionen umzugehen (funktionale Programmiertechniken). Sie glauben, dass Java Sprache ist objektorientiert und Daher sollten sie dieses Problem mit objektorientierten Techniken lösen und nicht auf die Einfachheit und Konsistenz der Sprache Java) verzichten.

Daher verwenden sie Schnittstellen. Wenn ein Objekt einer Schnittstelle mit nur einer Methode (ich meine funktionale Schnittstelle) benötigt wird, können Sie es durch einen Lambda-Ausdruck ersetzen. Sowie:

ActionListener listener = event -> ...;
1
MMKarami

Funktionsschnittstelle:

  • Eingeführt in Java 8
  • Schnittstelle, die eine "einzelne abstrakte" Methode enthält.

Beispiel 1:

   interface CalcArea {   // --functional interface
        double calcArea(double rad);
    }           

Beispiel 2:

interface CalcGeometry { // --functional interface
    double calcArea(double rad);
    default double calcPeri(double rad) {
        return 0.0;
    }
}       

Beispiel 3:

interface CalcGeometry {  // -- not functional interface
    double calcArea(double rad);
    double calcPeri(double rad);
}   

Java8-Anmerkung - @FunctionalInterface

  • Überprüfen Sie, ob die Schnittstelle nur eine abstrakte Methode enthält. Wenn nicht, Fehler auslösen.
  • Obwohl @FunctionalInterface fehlt, ist es immer noch eine funktionierende Schnittstelle (wenn es eine einzelne abstrakte Methode gibt). Die Anmerkung hilft, Fehler zu vermeiden.
  • Die Funktionsschnittstelle verfügt möglicherweise über zusätzliche statische und Standardmethoden.
  • z.B. Iterable <>, Comparable <>, Comparator <>.

Anwendungen der funktionalen Schnittstelle:

  • Methodenreferenzen
  • Lambda-Ausdruck
  • Konstruktorreferenzen

Um funktionale Schnittstellen zu erlernen, lernen Sie zunächst die Standardmethoden in der Schnittstelle. Nach dem Erlernen der funktionalen Schnittstelle ist es für Sie einfach, die Methodenreferenz und den Lambda-Ausdruck zu verstehen

1
Ketan