Vergleichen Sie Java 8 Optional mit Swift

Überblick

In diesem Artikel, basierend auf den Elementen in der Übersicht über Optionale offizielle Apple-Dokumente, Swifts "Optional" -Typ und Java 8 Vergleichen Sie die optionalen Typen. Obwohl der Inhalt jetzt ein wenig erfrischend ist, habe ich ihn als persönliches Memorandum veröffentlicht. Ende des Artikels enthält auch eine Vergleichstabelle für jede Notation. Bitte schauen Sie sie alle zusammen an. Die Schnipsel in diesem Artikel wurden ein wenig vereinfacht, sodass einige davon nicht funktionieren, selbst wenn Sie sie so kopieren und einfügen, wie sie sind. Bitte beachten Sie.

Null-Koaleszenz-Operator

Swift

Packt Optinal aus, um den Inhalt (falls vorhanden) oder den angegebenen Standardwert anderweitig zurückzugeben. Verwenden Sie den Operator ??. Sie können auch mehrere optionale Typen als Operanden verbinden.

Swift


let wrappedValue: String? = nil
let defaultValue = "default"
let value = wrappedValue ?? defaultValue
print(value)
// "default"

Swift


let wrappedValue: String? = nil
let defaultValue = "default"

let otherWrappedValue: String? = nil
//Solange der richtige Operand optional ist??Kann verbunden werden mit
let value = wrappedValue ?? otherWrappedValue ?? defaultValue
print(value)
// "default"

Java 8

In Java 8 ist es kein Operator, sondern eine Methode namens "orElse", "orElseGet". "orElse" übergibt den Standardwert selbst und "orElseGet" übergibt ein Objekt vom Typ "Supplier <? Extends T>", das den Standardwert bereitstellt. Beide Methoden geben jedoch einen umschlossenen Typ zurück, sodass Sie nicht mehrere optionale Typen wie Swift mit orElse verbinden können.

Java


Optional<String> wrappedValue = Optional.empty();
String defaultValue = "default";
String value = wrappedValue.orElse(defaultValue);
System.out.println(value);
// "default"

String otherValue = wrappedValue.orElseGet( () -> defaultValue );
System.out.println(otherValue);
// "default"

Java


Optional<String> otherWrappedValue = Optional.of("other");
//Ich kann das nicht machen
// String unwrappedValue = wrappedValue.orElse(otherWrappedValue).orElse(defaultValue);

Kurzschlussauswertung

Swift

Der Nil-Join-Operator von Swift bewertet den Kurzschluss. Daher wird der rechte Operand nur ausgewertet, wenn der linke Operand "Null" ist.

Swift


func hoge() -> String {
    print("called")
    return "hoge"
}

let value = nil ?? hoge()
print(value)
// "called"
// "hoge"

//Da es sich um eine Kurzschlussauswertung handelt, hoge()Wird nicht genannt
let value = "non nil" ?? hoge()
print(value)
// "non nil"

Java 8

Java 8 oder ElseGet ist ebenfalls eine Kurzschlussauswertung, ** oder Else jedoch nicht **. Dies ist natürlich, da der Standardwert selbst übergeben wird.

Java


public String hoge() {
    System.out.println("called");
    return "hoge";
}

String value = Optional.<String>empty().orElseGet(this::hoge);
System.out.println(value);
// "called"
// "hoge"

//Da es sich um eine Kurzschlussauswertung handelt, hoge()Wird nicht genannt
String value = Optional.of("non null").orElseGet(this::hoge);
System.out.println(value);
// "non null"

Java


//orElse bewertet keinen Kurzschluss
String value = Optional.of("non null").orElse(hoge());
System.out.println(value);
// "called"
// "non null"

In Bezug auf die ordnungsgemäße Verwendung ist es besser, "orElseGet" für die Kurzschlussbewertung zu verwenden, wenn die Generierung des Standardwerts Geld kostet.

Java


public String fetchValue() {
    //Zeitaufwändiger Prozess
    return result;
}

// △ -Stellen Sie sicher, dass Sie den Wert abrufen()Wird aufgerufen, wirkt sich dies zumindest auf die Leistung aus
String value = wrappedValue.orElse(fetchValue());
// ◯ -Da es sich um eine Kurzschlussauswertung handelt, wird sie nicht aufgerufen, wenn Inhalt vorhanden ist
String value = wrappedValue.orElseGet(this::fetchValue);

Java


// △ -Wenn es Inhalte gibt, ist dies eine nutzlose Objekterzeugung
Person person = wrappedPerson.orElse(new Person());
// ◯ -Da es sich um eine Kurzschlussauswertung handelt, wird kein Objekt erstellt, wenn Inhalt vorhanden ist
Person person = wrappedPerson.orElseGet(Person::new);

Bedingungsloses Auspacken

Swift

Packt den Wert mit oder ohne Inhalt aus. Verwenden Sie den Operator !. Wenn es "Null" ist, verursacht es einen Laufzeitfehler.

Swift


let number = Int("42")!
print(number)
// 42

Java 8

Java 8 verwendet die Methode "get". Wenn es "null" ist, wird eine ungeprüfte Ausnahme "NoSuchElementException" ausgelöst.

Java


public Optional<Integer> intFromString(String string) {
    try {
        return Optional.of(Integer.parseInt(string));
    } catch (NumberFormatException ignored) {
        return Optional.empty();
    }
}

int number = intFromString("42").get();
System.out.println(number);
// 42

Umwandlung

Swift

Konvertieren Sie den Wert. Verwenden Sie eine Methode namens "map". Wenn Inhalt vorhanden ist, wird der Wert gemäß dem angegebenen Abschluss vom Typ "(Wrapped) -> U" konvertiert, und wenn er "Null" ist, wird er als "Null" ausgegeben. Daher wird der Typ "Optional" zurückgegeben.

Swift


let intString: String? = "42"
let percentage: String? = intString.map { "\($0)%" }
print(String(describing: percentage))
// Optional("42%")

Wenn Sie einen optionalen Typ in einem Abschluss zurückgeben möchten, verwenden Sie die Methode flatMap, die einen Abschluss vom Typ (Wrapped) -> Optional <U> als Argument verwendet.

Swift


let intString: String? = "42"
// Int(String)Ist Int?Gib es zurück
let integer: Int? = intString.flatMap { Int($0) }
print(String(describing: integer))
// Optional(42)

Java 8

Java 8 verwendet auch die Methoden map und flatMap. Die Verwendung ist die gleiche.

Java


Optional<String> intString = Optional.of("42");
Optional<String> percentage = intString.map( str -> str + "%" );
System.out.println(percentage);
// Optional[42%]

Java


Optional<String> intString = Optional.of("42");
Optional<Integer> integer = intString.flatMap(this::intFromString);
System.out.println(integer);
// Optional[42]

Optionale Bindung

Swift

Ich denke, es ist als sichere Auspackmethode bekannt. Durch die Kombination mit Schlüsselwörtern wie "if" und "guard" ist es möglich, den Prozess zu verzweigen, je nachdem, ob Inhalt vorhanden ist oder nicht.

Swift


let wrappedValue: String? = "value"
if let value: String = wrappedValue {
    print(value)
} else {
    print("no value")
}
// "value"

Swift


let wrappedValue: String? = "value"
guard let value: String = wrappedValue else {
    print("no value")
    return
}
print(value)
// "value"

Java 8

In Java 8 können Sie es sicher über eine Methode namens "ifPresent" entpacken. Es nimmt ein Objekt vom Typ "Consumer <? Super T>" als Argument und beschreibt die Verarbeitung, wenn sich ein Inhalt darin befindet.

Java


Optional<String> wrappedValue = Optional.of("value");
wrappedValue.ifPresent( str -> {
    System.out.println(str);
});
// "value"

Es gibt jedoch keine ** Methode, die die Verarbeitung beschreiben kann, wenn kein Inhalt vorhanden ist **. Wenn Sie beide Prozesse beschreiben möchten, müssen Sie daher "isPresent" verwenden, um die Existenz des Inhalts zu überprüfen. Es ist jedoch im Vergleich zu Swift redundant, da Sie das erzwungene Entpacken "get" explizit beschreiben müssen, wenn Inhalt ** vorhanden ist.

Java


Optional<String> wrappedValue = Optional.of("value");
if (wrappedValue.isPresent()) {
    //Redundant, muss aber explizit zum Auspacken gezwungen werden
    String value = wrappedValue.get();
    System.out.println(value);
} else {
    System.out.println("no value");
}
// "value"

Java


Optional<String> wrappedValue = Optional.of("value");
//Beschreiben Sie in der Kartenklausel
if (!wrappedValue.isPresent()) {
    System.out.println("no value");
    return;
}
//Redundant, muss aber explizit zum Auspacken gezwungen werden
String value = wrappedValue.get();
System.out.println(value);
// "value"

Java


Optional<String> wrappedValue = Optional.of("value");
wrappedValue.ifPresent( str -> {
    System.out.println(str);
})// .orElse( () -> { //Ich kann das nicht machen
//     System.out.println("no value");
// })
;

Da der an ifPresent übergebene Umfang des Prozesses innerhalb des Lambda-Ausdrucks liegt, kann die aufrufende Methode innerhalb dieses Prozesses nicht zurückgegeben werden. Wenn Sie also frühzeitig zurückkehren möchten, haben Sie keine andere Wahl, als "isPresent" zu verwenden.

Java


public boolean foo(Optional<String> wrappedValue) {
    //Kehre früh zurück, wenn es einen Wert gibt
    if (wrappedValue.isPresent) {
        String str = wrappedValue.get();
        //Etwas tun
        return true;
    }
    //Was tun, wenn kein Wert vorhanden ist?
    return result;
}

Java


public boolean foo(Optional<String> wrappedValue) {
    //Kehre früh zurück, wenn es einen Wert gibt
    wrappedValue.ifPresent( str -> {
        //Etwas tun
//         return true; //Dies ist nicht möglich, da der Gültigkeitsbereich innerhalb dieses Lambda-Ausdrucks liegt
    });
    //Was tun, wenn kein Wert vorhanden ist?
    return result;
}

Optionale Verkettung

Swift

Greifen Sie nur dann auf Eigenschaften und Methoden zu, wenn Inhalt vorhanden ist. Verwenden Sie den Postfix-Operator ?.

Swift


let wrappedValue: String? = "value"
let uppercased: String? = wrappedValue?.uppercased()
print(String(describing: uppercased))
// Optional("VALUE")

Swift


class Hoge {
    func hoge() { print("hoge") }
}

let wrappedValue: Hoge? = Hoge()
wrappedValue?.hoge()
// "hoge"

Java 8

In Java 8 können Sie die zuvor eingeführte map -Methode verwenden. Wenn das Ziel eine Methode ist, kann es mithilfe einer Methodenreferenz präzise geschrieben werden. Wenn das Ziel jedoch einen optionalen Typ zurückgibt, müssen Sie flatMap verwenden.

Java


Optional<String> wrappedValue = Optional.of("value");
Optional<String> uppercased = wrappedValue.map(String::toUpperCase);
System.out.println(uppercased);
// Optional[VALUE]

Java


class User {
    final String id;
    Optional<String> mail = Optional.empty();
    User(String id) { this.id = id; }
}

Optional<User> wrappedUser = Optional.of(new User("user1"));
Optional<String> mail = wrappedUser.flatMap( user -> user.mail );
System.out.println(mail);
// Optional.empty

Es ist genau die gleiche Notation wie bei Verwendung von Konvertieren, einschließlich der richtigen Verwendung. Java 8 bietet keine spezielle Notation oder Methode, um nur auf das Feld oder die Methode des umschlossenen Werts zuzugreifen. Verwenden Sie das zuvor eingeführte "ifPresent", um auf Methoden zuzugreifen, die keinen Wert zurückgeben.

Java


class Hoge {
    void hoge() { System.out.println("hoge"); }
}

Optional<Hoge> wrappedValue = Optional.of(new Hoge());
wrappedValue.ifPresent(Hoge::hoge);
// "hoge"

Zusammenfassung

In diesem Artikel haben wir Java 8- und "Optional" -Typen basierend auf der Behandlung von "Optional" -Typen in Swift verglichen. Unten finden Sie eine Vergleichstabelle für jede Notation. Besonders wenn es um optionales Binden und optionales Verketten geht, ist der Unterschied zwischen beiden sehr offensichtlich. Die optionale Java 8-Bindung ist etwas redundanter als Swift, da sie nicht gleichzeitig mit der Verzweigung entpackt werden kann. Außerdem bietet Java 8 keine dedizierte Möglichkeit, auf umschlossene Werte zuzugreifen, wie z. B. Swifts ? Operator.

Swift Java
Kein Join-Operator ?? orElse* Bewertung des Kurzschlusses
orElseGet
Erzwungenes Auspacken ! get
Umwandlung map
flatMap
map
flatMap
Optionale Bindung if let
guard let
ifPresent
OderisPresentNach der Verzweigung beigetErzwungenes Auspacken mit
Optionale Verkettung ? OptionalWenn Sie den Typ zurückgeben möchtenflatMap
Wenn Sie etwas anderes zurückgebenmap
Wenn es keinen Wert zurückgibtifPresent

Wenn Sie Fehler haben, teilen Sie uns dies bitte in den Kommentaren mit.

Bonus-Java 9 Optional

Hier werden wir die "optionalen" Methoden "or" und "ifPresentOrElse" vorstellen, die in Java 9 hinzugefügt wurden. Ich kann nicht über Java 8 sprechen. Es ist ein vollständiger Bonus.

or

Führt ein Objekt vom Typ "Lieferant <? Erweitert Optional <? Erweitert T >>" aus, wenn es leer ist, um den Standardwert vom Typ "Optional" zu erhalten. Dies ist genau der Fall, wenn Swifts Nil-Join-Operator den Typ "Optional" auf den richtigen Operanden bringt. Aufgrund der ** Kurzschlussbewertung ** wird das angegebene "Lieferanten" -Objekt nicht ausgeführt, solange es Inhalt enthält.

Swift


let wrappedValue: String? = nil
let defaultValue = "default"

let otherWrappedValue: String? = nil
let value = wrappedValue ?? otherWrappedValue ?? defaultValue
print(value)
// "default"

Java


// available Java 9 or later
Optional<String> wrappedValue = Optional.empty();
String defaultValue = "default";

Optional<String> otherWrappedValue = Optional.empty();
//Der optionale Typ kann in Java 9 oder höher als Standardwert angegeben werden
String value = wrappedValue.or( () -> otherWrappedValue ).orElse(defaultValue);
System.out.println(value);
// "default"

ifPresentOrElse

Sie können den Prozess verzweigen, je nachdem, ob er Inhalt enthält oder nicht. Wenn Inhalt vorhanden ist, wird ein Objekt vom Typ "Consumer <? Super T>" ausgeführt, andernfalls wird ein Objekt vom Typ "Runnable" ausgeführt. Da Sie die Verarbeitung auch beschreiben können, wenn sie "null" ist, ist sie der optionalen Bindung von Swift im Vergleich zu Java 8 viel näher.

Swift


let wrappedValue: String? = "value"
if let value = wrappedValue {
    print(value)
} else {
    print("no value")
}
// "value"

Java


// available Java 9 or later
Optional<String> wrappedValue = Optional.<String>empty();
wrappedValue.ifPresentOrElse( str -> {
    System.out.println(str);
}, () -> {
    System.out.println("no value");
});
// "no value"

Recommended Posts

Vergleichen Sie Java 8 Optional mit Swift
Schreiben Sie Java Try-Catch mit Optional neu
[Java] Fassen Sie zusammen, wie Sie mit der Methode equals vergleichen können
Vergleiche Integer mit ==
24 Stunden mit Android-Entwicklung zu kämpfen, Java Optional
[Java] Optionales Memorandum
Java 9 Optional :: stream
Installieren Sie Java mit Homebrew
Installieren Sie Java mit Ansible
Bequemer Download mit JAVA
Java-Dokument von Java anzeigen Optional
Schalten Sie Java mit direnv
Swift Optionale Forschung
Listen in Java vergleichen
Erste Schritte mit Swift
Java-Download mit Ansible
Lass uns mit Java kratzen! !!
Beginnend mit Swift Swift UI
Erstellen Sie Java mit Wercker
Endian-Konvertierung mit JAVA
(Java) Einfache BDD mit Spektrum?
Verwenden Sie Lambda-Ebenen mit Java
Erste Schritte mit Java Collection
Java-Konfiguration mit Spring MVC
Grundlegende Authentifizierung mit Java 11 HttpClient
Experimentieren wir mit der Java-Inline-Erweiterung
Führen Sie Batch mit Docker-Compose mit Java-Batch aus
[Vorlage] MySQL-Verbindung mit Java
Installieren Sie Java 7 mit Homebrew (Fass)
[Java] JSON-Kommunikation mit Jackson
Java zum Spielen mit Function
Versuchen Sie eine DB-Verbindung mit Java
So behandeln Sie Ausnahmen mit Java 8 Stream oder Optional kühl
Verwendung von Java Optional
Aktivieren Sie Java EE mit NetBeans 9
[Java] JavaConfig mit statischer innerer Klasse
Versuchen Sie gRPC mit Java, Maven
Lassen Sie uns Excel mit Java betreiben! !!
Java-Versionsverwaltung mit SDKMAN
RSA-Verschlüsselung / Entschlüsselung mit Java 8
Paging PDF mit Java + PDFBox.jar
Sortieren Sie Zeichenfolgen als charakteristische Funktion mit Java
Objektorientiert mit Strike Gundam (Java)
[Java] Inhaltserfassung mit HttpCliient
Java-Versionsverwaltung mit jenv
Fehlerbehebung mit Java Flight Recorder
Optimieren Sie Java-Tests mit Spock
Stellen Sie mit Java eine Verbindung zur Datenbank her
Stellen Sie mit Java eine Verbindung zu MySQL 8 her
Verwenden von Mapper mit Java (Spring)
Java Study Memo 2 mit Progate
[Swift] Ich dachte über Vergleiche nach
Erste Schritte mit Java Basics
Verwenden Sie SpatiaLite mit Java / JDBC
Stellen Sie sicher, dass Sie das Java compareTo-Ergebnis mit 0 vergleichen
Lernen von Java mit Progate Note 1