Es ist etwas mehr als zwei Jahre her, seit ich in die IT-Branche eingestiegen bin. Um ehrlich zu sein, arbeite ich erst seit etwas mehr als einem Jahr ernsthaft an der Codierung. Gleichzeitig hat es aufgrund von Betrieb und Wartung in einer positiven Welt gelebt, bestehende Implementierungen zu verbessern, um sie nicht so stark wie möglich zu verschmutzen. Und schließlich ist das in diesem Paket verwendete JDK Java 1.7! !! Vor dem obigen Hintergrund habe ich Java8 oder höher selten berührt, deshalb wollte ich es wieder lernen. Während ich auch als Memorandum diene, möchte ich in Zukunft ernsthaft für Qiita schreiben, deshalb habe ich mich entschlossen, diesmal zu schreiben.
In einem ersten Schritt war mein Verständnis des Lambda-Ausdrucks vage, daher möchte ich mein Verständnis durch den Artikel vertiefen.
Es scheint, dass einige Grundkenntnisse über funktionale Schnittstellen erforderlich sind, um plötzlich Lambda-Ausdrücke zu verstehen. Was ist dann überhaupt eine Schnittstelle? Ich kann nicht klar antworten, wenn ich gefragt werde. Haben Sie keine Angst, ein solides Verständnis der Java-Schnittstellen zu erlangen.
Ich denke, die folgenden Artikel sind leicht zu verstehen und hilfreich. https://www.internetacademy.jp/it/programming/java/difference-between-interface-and-abstract.html
Eine Schnittstelle bereitet nur eine Box mit Methoden vor, und wenn die Box tatsächlich verwendet wird (Vererbung), muss die geerbte Klasse sie implementieren. Stellen Sie sich beispielsweise eine Situation vor, in der "EmployeeService" als Serviceklasse für eine Entität mit dem Namen "Employee" implementiert ist.
EmployeeService.java
interface EmployeeService {
Employee getEmployee(String pk);
}
Eine übliche (gebrauchte) Implementierung der Service-Klasse besteht darin, die Service-Schnittstelle zu implementieren und nur die Methoden der Außenwelt zugänglich zu machen. Erstellen Sie "EmployeeServiceImpl" in einer anderen Klasse als Implementierungsklasse von "EmployeeService".
EmployeeServiceImpl.java
public class EmployeeServiceImpl implements EmployeeService {
Employee getEmployee(String pk) {
//Gehen Sie zu Dao und holen Sie sich den Mitarbeiter, der zu pk passt.
return employeeDao.find(pk);
}
}
Wichtig hierbei ist, dass dieses "EmployeeServiceImpl" von "EmployeeService" erbt. Dies bedeutet, dass Sie "getEmployee" implementieren müssen, das in "EmployeeService" deklariert ist. Auf diese Weise muss die Implementierungsklasse, die die Schnittstelle erbt, die in der Schnittstelle deklarierte Methode implementieren, was zu einem Kompilierungsfehler führt, und die Implementierung kann erzwungen werden.
Der größte Unterschied zwischen einer abstrakten Klasse und einer Schnittstelle besteht darin, dass sie mehrfach vererbt werden kann. Ich werde nicht auf Details zur Mehrfachvererbung eingehen, aber der Punkt ist, dass Sie einen Mechanismus verwenden können, der mehrere Implementierungen in einer Schnittstelle erzwingt. (Eine Klasse kann mehrere Schnittstellen erben.)
Ich verstehe die Schnittstelle. Ich verstehe, aber ich habe immer noch genug Wissen, um die Lambda-Formel zu verstehen. Was ist eine funktionale Schnittstelle? Hmm, was ist ein "Funktionstyp"? Hmm, was ist eine Funktion?
Die folgende URL ist hilfreich für eine Funktion. https://stackoverflow.com/questions/155609/whats-the-difference-between-a-method-and-a-function
Kurz gesagt, eine Funktion ist `Derjenige, der einen bestimmten Parameter (Argument) empfängt, eine Verarbeitung basierend auf dem Argument durchführt und den Ergebniswert (return) zurückgibt. ``
Bei der Implementierung einer Funktion sind einige Punkte zu beachten, daher werde ich sie hier vorstellen. Wenn Sie in einer Sprache wie Java programmieren, hören Sie früher oder später das Wort "Nebenwirkungen". Grob gesagt sind Nebenwirkungen ... Ich verstehe, dass es sich um eine Implementierung handelt, bei der das Ausführungsergebnis einer Funktion nicht immer konstant ist.
Hier sind einige Dinge zu beachten, um eine Funktion zu implementieren, die keine Nebenwirkungen hat:
Bitte überprüfen Sie separat nach spezifischen Implementierungsbeispielen. (Es gibt 50.000 Artikel, die besser erklären als ich.)
Zurück zur Geschichte: Eine Funktion ist schließlich ein Wert, der einen Wert für die Eingabe zurückgibt.
Ich habe eine ungefähre Vorstellung von den Funktionen. Was ist eine funktionale Schnittstelle? Lassen Sie uns das Thema auf die Geschichte verschieben. Die folgenden Artikel sind sehr hilfreich, deshalb werde ich sie beschreiben. http://www.ne.jp/asahi/hishidama/home/tech/java/functionalinterface.html#h_outline
Was ist, wie in diesem Artikel erwähnt, eine funktionale Schnittstelle?
Eine Schnittstelle mit nur einer definierten abstrakten Methode.
darüber.
Der in diesem Artikel vorgestellte "EmployeeService" kann als funktionale Schnittstelle bezeichnet werden. Eine "Service" -Klasse, die nur einen "Employee" abruft und zurückgibt, der dem "pk" entspricht.
EmployeeService.java
@FunctionalInterface
public interface EmployeeService {
Employee getEmployee(String pk);
}
Der Punkt beim Definieren einer funktionalen Schnittstelle ist die Annotation @ FunctionalInterface
.
Durch Hinzufügen dieser Annotation kann explizit deklariert werden, dass es sich um eine funktionale Schnittstelle handelt. Wenn die Bedingungen auch zur Kompilierungszeit nicht erfüllt sind, tritt ein Fehler auf.
Wenn Sie diese Anmerkung auch nach der Implementierung hinzufügen, können andere leichter verstehen, dass es sich um eine funktionale Schnittstelle handelt.
Ab JDK1.8 werden funktionale Schnittstellen (Schnittstellen, die nur eine abstrakte Methode enthalten) als speziell behandelt. Nun, ich bin endlich zum Hauptthema dieses Artikels zurückgekehrt. Was ist der Lambda-Typ von hier aus? Ich werde versuchen es herauszufinden.
Der folgende Artikel ist sehr einfach zu verstehen und hilfreich, da er den Lambda-Ausdruck veranschaulicht. http://masatoshitada.hatenadiary.jp/entry/2015/02/09/190150
Um Lambda-Ausdrücke zu verstehen, ist es meines Erachtens am besten, die Typinferenz am Beispiel der Funktion zu verstehen.
Function ist ein in Java 8 eingeführtes Paket.
Der Typ wird durch Function <T, R>
definiert, T
ist der Typ, der das Argument sein soll, und R
ist der Typ, der als Rückgabewert zurückgegeben werden soll.
Diese "Funktion" ist also als funktionale Schnittstelle definiert und hat nur eine Methode namens "Apply".
Sie können Lambda-Ausdrücke verwenden, um Function
zu implementieren.
Ein einfaches Implementierungsbeispiel ist unten dargestellt.
Beispiel) Holen Sie sich den "Namen" des "Mitarbeiters" mit "Funktion".
Employee.java
@Getter
@Setter
@AllArgsConstructor(staticName = "of")
public class Employee {
/** Id */
private int id;
/** Name */
private String name;
}
Main.java
pubic class Main {
public static void main(String args[]){
Employee emp = Employee.of(1, "Probieren Sie Taro")
Function<Employee, String> getEmployeeName = employee -> employee.getName();
String empName = getEmployeeName.apply(emp);
System.out.println(empName); //"Sample Taro" wird ausgegeben.
}
}
Hier ist der wichtige Punkt im obigen Beispiel.
Function<Employee, String> getEmployeeName = employee -> employee.getName();
Function
hat den Prozess, den String-Typ ( String
), der das Ergebnis von employee.getName ()
als Rückgabewert ist, vom Typ ( Employee
) zurückzugeben, der das Argument von Function
ist. Implementieren Sie es in einer Methode namens "apply".
Dies geschieht nach der Lambda-Formel.
Java interpretiert "Mitarbeiter" als "Mitarbeiter", was "T" in "Typinferenz" ist, und Java interpretiert, dass der Wert für "Rückgabe" in "Typinferenz" "Zeichenfolge" ist. (Es ist klug ...)
String empName = getEmployeeName.apply(emp);
Und tatsächlich, im obigen Teil, wende apply
of Function
auf empName
of String an.
Lambda-Ausdrücke haben den Vorteil, dass die Beschreibung funktionaler Schnittstellen vereinfacht wird.
Schließlich ist der Lambda-Ausdruck, den ich verstanden habe, praktisch und nutzt die Typinferenz vollständig aus, um die Implementierung bei der Implementierung einer funktionalen Schnittstelle zu vereinfachen. Die Verwendungsszenen des Lambda-Typs allein sind begrenzt, und ich frage mich, ob der Lambda-Typ in Kombination mit "Function" und "Stream" wirklich sein volles Potenzial zeigt. Es ist nicht immer notwendig, diesen Lambda-Ausdruck zu kennen, wenn man "stream" verwendet, aber es lohnt sich, ihn zu verstehen.
Ich denke darüber nach, "Optional" neu zu lernen, aber anscheinend handelt es sich um einen Lambda-Ausdruck (oder besser "Verbraucher"). Das Schreiben eines Artikels wird Ihr Verständnis verbessern + es wird eine Erinnerung sein, daher möchte ich auch in Zukunft aktiv schreiben.
Wenn Sie Fehler oder Ratschläge haben, hinterlassen Sie bitte einen Kommentar ...!
Das nächste Mal möchte ich einen Artikel über "Optional" schreiben. Bis bald ~