Verstehen Sie, wie die funktionale Programmierung in Java auf einen Schlag eingeführt wurde

Einführung

Ich habe Java SE8 Gold und kann jetzt die Funktionsschnittstelle, den Lambda-Ausdruck und die Stream-API verwenden, die die meisten Fragen beschäftigten, aber was ist es schließlich? Es war in einem Zustand.

Daher habe ich beschlossen, zusammenzufassen, warum die funktionale Programmierung überhaupt eingeführt wurde und wie die Idee von funktionalen Schnittstellen und Lambda-Ausdrücken geboren wurde. (~~ Vor der Prüfung zusammenfassen ~~)

Lehrprogrammierung und Funktionsprogrammierung

Java hat die Lehrprogrammierung gebilligt!

Schauen Sie sich plötzlich den folgenden Code an.

  public static void findMatsumoto(List<String> names) {

    boolean found = false;

    for (String name : names) {
      if (name.equals("Matsumoto")) {
        found = true;
        break;
      }
    }
     
    if (found)
      System.out.println("Found Matsumoto");
    else
      System.out.println("Sorry, Matsumoto not found");
  }

Es ist eine sehr einfache Methode. Die als Argument übergebene Namensliste wird Element für Element wiederholt, um zu überprüfen, ob sie mit Matsumoto übereinstimmt. Wenn es ein Element gibt, das mit Matsumoto übereinstimmt, setzen Sie die zuvor vorbereitete lokale Variable auf true und verlassen Sie die Schleife. Wenn gefunden wahr ist, wird schließlich "gefundenes Matsumoto" angezeigt, und wenn gefunden falsch ist, wird "Entschuldigung, Matsumoto nicht gefunden" angezeigt.

Wie oben erwähnt, ist diese Methode in der sogenannten "** Befehlsprogrammierung **" geschrieben, die alle Schritte zum Wiederholen jedes Elements, Vergleichen von Werten, Setzen von Flags und Verlassen der Schleife definiert. Ich werde.

Was passiert, wenn Sie versuchen, in funktionaler Programmierung zu schreiben?

Wenn Sie versuchen, die Methode von ↑ durch funktionale Programmierung zu beschreiben, ist dies wie folgt.

public static void findMatsumoto(List<String> names) {

  if (names.contains("Matsumoto"))
    System.out.println("Found Matsumoto");
  else
    System.out.println("Sorry, Matsumoto not found");

}

Es ist viel sauberer als das Programmieren von Anweisungen, nicht wahr? Insbesondere beschreibt der Funktionstyp keine Schleifenverarbeitung. Die Methode includes kümmert sich um alles, und der Entwickler hat nichts damit zu tun, wie es gemacht wird. Mit nur dieser Beschreibung können Sie jedoch das erwartete Ergebnis erzielen.

Mit anderen Worten, das Schreiben in funktionaler Programmierung kann im Vergleich zur imperativen Programmierung zu ** prägnantem und leicht verständlichem Code ** führen.

★ Referenzen [1] [Abkürzung zum Übergang zur funktionalen Programmierung - Einführung funktionaler Methoden in Java-Programme mit deklarativer Denkweise](https://www.ibm.com/developerworks/jp/java/library/j- java8idioms1 / index.html)

Es gibt viele andere Vorteile der funktionalen Programmierung!

Neben der Vereinfachung und Verständlichkeit des Codes bietet die funktionale Programmierung viele Vorteile.

In der Funktionsprogrammierung haben Funktionen die folgenden Eigenschaften. ** ● Gibt immer das gleiche Ergebnis für den eingegebenen Wert zurück ** ** ● Funktionsbewertung hat keine Auswirkungen auf andere **

Die folgenden Methoden können als Funktionen bezeichnet werden.

public int add(int x, int y) {

  return x + y;

}

Es wird immer das gleiche Ergebnis für die Eingaben (x und y) zurückgegeben, und die Auswertung hier hat keinen anderen Effekt.

Können die folgenden Methoden andererseits als Funktionen bezeichnet werden?

public int add(int y) {

  return x += y; //x ist eine Variable, die außerhalb der Methode definiert ist

}

Diese Methode gibt nicht immer das gleiche Ergebnis für die Eingabe y zurück. (Abhängig von der externen Variablen x.) Dies wirkt sich auch auf die externe Variable x aus. Aus den oben genannten Gründen kann diese Methode nicht als Funktion bezeichnet werden.

Aufgrund der obigen Eigenschaften können die folgenden Vorteile mithilfe der Funktion berücksichtigt werden. ** 1. Einfach zu testen ** Sie müssen nur einen Testfall berücksichtigen, da für den von Ihnen eingegebenen Wert immer das gleiche Ergebnis zurückgegeben wird.

** 2. Sehr sicher ** Da die Auswertung durch die Funktion keinen Einfluss auf andere hat, ist sie ohne unerwartete Änderungen sehr sicher.

** 3. Optimieren Sie die Parallelverarbeitung ** Es ist für die Parallelverarbeitung geeignet, da die Funktionen nicht voneinander abhängen. In den letzten Jahren hat sich die Verbesserung der Single-Core-Leistung verlangsamt, und die CPU-Architektur ist in der Regel mehrkernig mit mehr Kernen. Es wird erwartet, dass die Verwendung von Funktionen diesem Trend zum Multi-Core entspricht. Mit anderen Worten ist es möglich, die Effizienz der Parallelverarbeitung zu verbessern und die Verarbeitungsgeschwindigkeit zu verbessern.

Bemerkenswerte Eigenschaften der funktionalen Programmierung

Darüber hinaus gibt es zwei bemerkenswerte Eigenschaften der funktionalen Programmierung: ** ● Sie können eine Funktion als Argument einer Funktion übergeben ** ** ● Sie können die Funktion als Rückgabewert der Funktion übergeben **

Ich möchte ein konkretes Beispiel mit "** Haskell **" zeigen, das als funktionale Programmiersprache bekannt ist.

Das folgende Programm gibt den Gesamtwert der Elemente des Arrays aus.

haskell


ary = [ 1, 3, 5, 7, 9 ]
main = print $ foldl (+) 0 ary

Die (+) Funktion wird als erstes Argument einer Funktion namens foldl übergeben. Gibt den Gesamtwert der Elemente des Arrays zurück, die im 3. Argument übergeben wurden, wobei 0 der Anfangswert im 2. Argument ist. Sie können sehen, dass es sehr präzise geschrieben ist.

Wenn Sie versuchen, dasselbe in Java zu tun,

Java



public static int addAll(int[] ary) {

    int total = 0;

    for (int i : ary) {
        total += i;
    }

    return total;
}

public static void main(String[] args) {
    int[] ary = { 1, 3, 5, 7, 9 };
    System.out.println(addAll(ary));
}

Es wird sein. Ich schreibe einen Schleifenprozess, daher ist der Code etwas lang.

Wenn Sie die funktionale Programmierung verwenden, können Sie den Prozess der Anzeige der Elemente eines Arrays auf der Konsole in ** nur einer Zeile ** beschreiben, sodass der Unterschied in der Menge der Beschreibung offensichtlich ist.

****** Bisher habe ich nur die Vorteile der funktionalen Programmierung behandelt, aber ich denke nicht blind, dass funktionale Programmierung die beste ist !!! ** Zur Verdeutlichung des Hintergrunds ** Nur die Vorteile werden in Anspruch genommen. Die Überlegenheit und Unterlegenheit der funktionalen Programmierung, der Anweisungsprogrammierung und der prozeduralen Programmierung geht über den Rahmen dieses Dokuments hinaus und wird nicht erörtert. (Manchmal bin ich mit funktionaler Programmierung nicht so vertraut, dass ich sie selbst diskutieren kann.)

★ Referenzen [2] Gehen wir zur funktionalen Programmierung ~ Der Eingang zum funktionalen Eingang, den jeder von Java liebt [3] Lassen Sie uns die Leistungsfähigkeit der funktionalen Programmierung kennen - Teil 2

Wenn es so viele Vorteile gibt, sollten Sie die funktionale Programmierung auch in Java einführen!

Ich habe es schon lange geschrieben, aber um es kurz zusammenzufassen, funktionale Programmierung hat viele Vorteile, und lassen Sie uns es in Java einführen! Es wurde. Obwohl es große Vorzüge hat, war es wegen der Herausforderungen gleichzeitig nicht einfach.

Probleme bei der Integration des Wesens der funktionalen Programmierung in Java

Wie Sie aus der Art der Funktionen in der funktionalen Programmierung ersehen können, "Sie können eine Funktion als Argument einer Funktion übergeben", beachten Sie bitte, dass "Funktion in der funktionalen Programmierung" = "Methode".

Um etwas näher darauf einzugehen, behandelt die funktionale Programmierung eine Funktion als erstklassiges Objekt, sodass Sie eine Funktion als Funktionsargument übergeben können. Da ein erstklassiges Objekt in Java jedoch eine Klasse ist, ** wird eine Methode als Methodenargument verwendet. Es kann nicht übergeben werden **.

Einführung in "Functional Interface"

Wie bereits erwähnt, können Sie in Java keine Methode als Methodenargument übergeben. Wenn es sich jedoch um ein Objekt (eine Instanz) handelt, können Sie es als Argument übergeben!

Also habe ich ein ** funktionsähnliches Objekt ** gemacht! Dann wurde "** Funktionsschnittstelle **" entwickelt.

Was ist eine funktionale Schnittstelle?

Es ist eine "funktionale Schnittstelle", die als funktionsähnliches Objekt erstellt wurde, aber wie folgt definiert ist.

** ● Schnittstelle mit einer einzelnen abstrakten Methode (SAM-Schnittstelle) **

Spezifisches Beispiel für eine funktionale Schnittstelle

@FunctionalInterface
public interface Example {
    public int calc(int x);      //Abstrakte Methode (SAM)
    static void say() { }        //statische Methode
    default void hello() { }     //Standardmethode
    public String toString();    //Öffentliche Methode der Objektklasse
}

Dies ist eine funktionale Schnittstelle!



** e? ** ** **

Wo ist es wie eine Funktion? Ich glaube, ich habe das gefühlt. Nun, es ist verständlich, wenn man es benutzt, also lasst uns tatsächlich ein Programm schreiben.

Verwenden Sie beim Übergeben eines Funktionsobjekts (Funktionstypschnittstelle) als Argument einer Methode die Notation "** anonyme innere Klasse **". Weitere Informationen zu anonymen inneren Klassen finden Sie in der Literatur [4].

//Funktionsschnittstelle
@FunctionalInterface
public interface Calc {
    public int add(int x, int y);    //Abstrakte Methode (SAM)
}

//Implementierung der Druckmethode mit Calc als Argument
private void print(int x, int y, Calc c) {
    System.out.println(c.add(x, y));
}

//Rufen Sie die Druckmethode auf
print(3, 4, new Calc() {
    @Override
    public int add(int x, int y) {
        return x + y;
    }
});

//Ausführungsergebnis 7

Wie oben beschrieben, ist es unter Verwendung der anonymen inneren Klasse möglich, die Funktionsschnittstelle Calc zu instanziieren, die abstrakte Methode add zu implementieren und sie an das Argument der Druckmethode zu übergeben.



** e? ** ** **

Die Menge an Beschreibungen ist überhaupt nicht gering und es fühlt sich nicht nach funktionaler Programmierung an! !!

Korrekt. Hier kommt der "** Lambda-Stil **" ins Spiel.

★ Referenzen [4] Anonyme innere Klasse [5] Einführung in Java8 Lambda [6] Funktionsschnittstelle - Erfahren Sie, wie Sie eine benutzerdefinierte Funktionsschnittstelle erstellen und warum Sie die integrierte Funktionsschnittstelle nach Möglichkeit immer verwenden sollten- /java/library/j-java8idioms7/index.html)

Wenn ich es im Lambda-Stil schreibe ...

Was ist ein Lambda-Typ?

Ein Lambda-Ausdruck ist eine Notation, die die Instanziierung einer Klasse vereinfacht, die eine abstrakte Methode einer funktionalen Schnittstelle implementiert (die zuvor in der anonymen inneren Klasse durchgeführt wurde).

Mal sehen, wie man es konkret weglässt. (1) Erstens ist aus der Typinferenz des Compilers ersichtlich, dass der Typ der Variablen, der an das dritte Argument der Druckmethode übergeben werden kann, ein Calc-Typ-Objekt ist, sodass "new Calc () {}" weggelassen werden kann.

(2) Da es sich bei der Calc-Schnittstelle um eine funktionale Schnittstelle handelt und nur eine abstrakte Methode vorhanden ist, ist es offensichtlich, diese zu überschreiben und zu implementieren, sodass auch "@ Override public int add" weggelassen werden kann.

(3) Schließlich ist der Argumenttyp auch durch Typinferenz ersichtlich, sodass er weggelassen werden kann. Wenn der Methodenblock ({}) weggelassen wird, kann auch das Schlüsselwort return weggelassen werden (in diesem Fall kann return nicht beschrieben, sondern weggelassen werden). Basierend auf dem oben Gesagten kann der obige Aufruf der Druckmethode wie folgt umgeschrieben werden.

//Rufen Sie die Druckmethode auf
print(3, 4, (x, y) -> x + y);

Oh, es ist wirklich kurz! Was wir tun, ist dasselbe wie für die anonyme innere Klasse. Wir implementieren die add-Methode add, um die Klasse zu instanziieren, aber die Beschreibung der neuen Operator- und Methodenüberschreibungen, die normalerweise für die Instanziierung erforderlich sind, lautet Es ist abgekürzt, daher sehr kurz und es sieht so aus, als würden Sie eine ** Funktion (Methode) übergeben, die ** direkt zum Argument der Methode hinzufügt.

Korrekt! !! Mit anderen Worten, ** mit Lambda-Ausdrücken abgekürzter Code sieht aus wie funktionale Programmierung **!

Beherrsche die Lambda-Formel

Sie haben festgestellt, dass Sie die funktionale Programmierung mithilfe einer Kombination aus funktionalen Schnittstellen und Lambda-Ausdrücken einführen können.

Das java.util.function-Paket von Java8 bietet eine universelle Schnittstelle vom Funktionstyp, und das Paket java.util.stream ist eine API zum Verarbeiten von Daten in einem Pipeline-Format mit einer Schnittstelle vom Funktionstyp als Argument. Es gibt viele Methoden. Natürlich können Sie auch eine benutzerdefinierte Funktionsoberfläche erstellen.

Das folgende Programm zeigt die Namen der Männer in der Namensliste an.

names.stream().filter(n -> n.getSex() == 0)
    .map(n -> n.getName())
    .forEach(System.out::println);

Ist es nicht einfach zu lesen und zu prägnant? Auf diese Weise kann eine gute Kombination aus Funktionsschnittstellen und Lambda-Ausdrücken, integrierten Funktionsschnittstellen und Stream-APIs die Funktionsprogrammierung einführen.

Ich möchte das Paket java.util.function und die Stream-API in einem separaten Artikel zusammenfassen.

★ Referenzen [7] [Gründliche Strategie Java SE 8 Gold Problem Collection](https://www.amazon.co.jp/ Gründliche Strategie-Java-Gold-Problem Collection-1Z0-809 / dp / 4295000035 / ref = sr_1_2? S = Bücher & ie = UTF8 & qid = 1538986245 & sr = 1-2 & keywords = java + gold + se8) [8] Java 8 Lambda-Ausdrücke verstehen

Zusammenfassung

Da die funktionale Programmierung viele Vorteile hat, möchte ich sie auch in Java einführen.   ↓ Durch die Vorbereitung eines Objekts (Funktionsschnittstelle) mit nur einer abstrakten Klasse anstelle einer Funktion und die Vereinfachung der Instanziierung der Klasse mithilfe von Lambda-Ausdrücken konnten wir die Funktionsprogrammierung in Java einführen! !!

Recommended Posts

Verstehen Sie, wie die funktionale Programmierung in Java auf einen Schlag eingeführt wurde
~ Ich habe jetzt versucht, funktionale Programmierung mit Java zu lernen ~
Wie man die Programmierung in 3 Monaten beherrscht
Einführung in die funktionale Programmierung (Java, Javascript)
Wie man JAVA in 7 Tagen lernt
Wie verwende ich Klassen in Java?
So benennen Sie Variablen in Java
So verketten Sie Zeichenfolgen mit Java
So erhöhen Sie den Wert von Map in einer Zeile in Java
So implementieren Sie die Datumsberechnung in Java
So implementieren Sie den Kalman-Filter mit Java
Mehrsprachige Unterstützung für Java Verwendung des Gebietsschemas
Java-Referenz zum Verständnis in der Abbildung
So führen Sie eine Basiskonvertierung in Java durch
So erzwingen Sie Codierungskonventionen in Java
Einbetten von Janus Graph in Java
So erhalten Sie das Datum mit Java
Verstehe in 5 Minuten !! Wie man Docker benutzt
Verwendung von credentials.yml.enc aus Rails 5.2
So zeigen Sie eine Webseite in Java an
So erhalten Sie eine Klasse von Element in Java
So verbergen Sie Nullfelder als Antwort in Java
So lösen Sie Ausdrucksprobleme in Java
Wie schreibe ich Java String # getBytes in Kotlin?
Gedanke: Wie man eine funktionale Schnittstelle für eigene Funktionen verwendet (Java)
Aufrufen von Funktionen in großen Mengen mit Java Reflection
So erstellen Sie eine Java-Umgebung in nur 3 Sekunden
[Java] So lassen Sie den privaten Konstruktor in Lombok weg
Wie kann ich IBM Mainframe-Dateien in Java eingeben / ausgeben?
Verstehen Sie, wie Sie den JSON-Decoder von Swift in 3 Minuten verwenden
So erstellen Sie einen Daten-URI (base64) in Java
In der Abbildung verstandene Java-Klassen und -Instanzen
So konvertieren Sie A in a und a in A mit logischem Produkt und Summe in Java
So konvertieren Sie eine Datei in ein Byte-Array in Java
So verwalten Sie Java EE-Projekte in Eclipse
Zusammenfassung der Implementierung von Standardargumenten in Java
Wie man altes Java (8er) in macOS 10.15 Catalina einfügt
Hinweise zur Verwendung regulärer Ausdrücke in Java
Wie man Arrays mit Java stapelweise initialisiert, wusste ich als Anfänger nicht
So erhalten Sie den Namen einer Klasse / Methode, die in Java ausgeführt wird
So lesen Sie Ihre eigene YAML-Datei (*****. Yml) in Java
Verwendung von JSON-Daten in der WebSocket-Kommunikation (Java, JavaScript)
Anmerkung: [Java] Überprüfen der in pom.xml beschriebenen groupId usw.
Speichern von Zeichenfolgen von ArrayList zu Zeichenfolge in Java (Personal)
Was ist in "Java 8 bis Java 11" passiert und wie wird eine Umgebung erstellt?
Aufrufen und Verwenden der API in Java (Spring Boot)
Verwendung des Java-Aufzählungstyps (Enum) in Mapper XML von MyBatis
Dynamisches Wechseln von JDKs beim Erstellen von Java mit Gradle
So entwickeln und registrieren Sie eine Sota-App in Java
So simulieren Sie das Hochladen von Post-Object-Formularen in OSS in Java
So stellen Sie eine Java-Anwendung in Alibaba Cloud EDAS in Eclipse bereit
So leiten Sie den letzten Tag des Monats in Java ab
Unterschiede im Umgang mit Zeichenfolgen zwischen Java und Perl
Eine Einführung in Funktionstypen für objektorientierte Programmierer in Elm
So wechseln Sie Java in der OpenJDK-Ära auf dem Mac
So senken Sie die Java-Version
[Java] Verwendung von Map
So deinstallieren Sie Java 8 (Mac)