So behandeln Sie Ausnahmen mit Java 8 Stream oder Optional kühl

Problem: Es ist umständlich, Ausnahmen mit Lambda-Ausdrücken zu behandeln

Verwenden Sie die Streams-API von Java8? Es ist sehr praktisch. Die Streams-API oder der Lambda-Ausdruck ist sehr leistungsfähig.

Die Lambda-Formel ist sehr mächtig, aber das Beispiel ist schlecht.java


Function<String, String> slice = x -> x.substring(3, 6);
System.out.println(slice.apply("abcdefghij")); // -> "def"

Wie viele darauf hingewiesen haben, ist [^ 1] nicht mit der Ausnahmebehandlung kompatibel, und es ist nicht möglich, Ausnahmen außerhalb von Lambda abzufangen. (Nein, ich denke, es ist natürlich, weil es ein Klumpen der Verarbeitung mit Lambda ist.)

Wenn im obigen Beispiel die Zeichenfolge aus 3 Zeichen oder weniger besteht, tritt ein Fehler auf. Fügen Sie daher die Ausnahmeverarbeitung ein, damit sie so zurückgegeben wird, wie sie ist, wenn ein Fehler auftritt.

Try Catch ist nicht cool und das Nesting ist tief und ich möchte, dass du aufhörst.java


Function<String, String> sliceAndCatch = x -> {
	try {
		return x.substring(3, 6);
	} catch (Exception e) {
		return x;
	}
};

System.out.println(sliceAndCatch.apply("abcdefghij")); // -> "def"
System.out.println(sliceAndCatch.apply("xy")); // -> "xy"

Wow, das Nest ist tief.

Außerdem müssen Sie bei einer Methode, die eine aktivierte Ausnahme auslöst, versuchen, im Lambda zu fangen, damit Sie hoge :: fuga nicht aufrufen können, das mit stream.map (hoge :: fuga) eine Ausnahme auslöst, wodurch Sie sich frustriert fühlen. .. Wenn es sich um eine nicht aktivierte Ausnahme handelt, kann sie zum Zeitpunkt des Aufrufs abgerufen werden (versuchen Sie es mit {stream.map (hoge :: fuga)} catch {~}), aber sie ist nicht sauber. Es gibt auch eine Bibliothek, die Stream und Optional umschließt, aber es ist ziemlich unpraktisch.

Lösung: Ich hoffe, Sie können in einer Zeile schreiben → Sie können auf diese Weise schreiben

Ich möchte das obige Beispiel mit einem Liner schreiben. Wenn Sie zwei Lambdas übergeben und die normale Verarbeitung für das erste Lambda und die Ausnahmeverarbeitung für das zweite Lambda schreiben, sieht es intelligent aus. Bereiten Sie also zunächst eine funktionale Schnittstelle vor, die Ausnahmen auslöst

Funktion, bei der eine Ausnahme ausgelöst wird.java


interface ThrowableFunction<T, R> {
	R apply(T t) throws Exception;
}

Und definieren Sie Versuchen Sie so

Das ganze Bild kommt in Sicht.java


public <T, R> Function<T, R> Try(ThrowableFunction<T, R> onTry, BiFunction<Exception, T, R> onCatch) {
	return x -> {
		try {
			return onTry.apply(x);
		} catch (Exception e) {
			return onCatch.apply(e, x);
		}
	};
}

Das allein ermöglicht eine coole Codierung!

Cool.java


Function<String, String> coolSlice = Try(x -> x.substring(3, 6), (error, x) -> x);

System.out.println(coolSlice.apply("abcdefghij")); // -> "def"
System.out.println(coolSlice.apply("xy")); // -> "xy"

Wenn der Verbraucher dasselbe tut,

Für Verbraucher.java


interface ThrowableConsumer<T> {
	void accept(T t) throws Exception;
}

public <T> Consumer<T> Try(ThrowableConsumer<T> onTry, BiConsumer<Exception, T> onCatch) {
	return x -> {
		try {
			onTry.accept(x);
		} catch (Exception t) {
			onCatch.accept(t, x);
		}
	};
}

Das ist auch cool!

Ich habs gemacht.java


Consumer<String> coolCatch = Try(x -> {System.out.println(Integer.valueOf(x));}, (error, x) -> error.printStackTrace());

coolCatch.accept("33"); //-> 33
coolCatch.accept("Hoge"); //-> java.lang.NumberFormatException: For input string: "Hoge"・ ・ ・

Verdienst und Fehler

Das Gute an dieser Methode

Schlechter Platz

Anwendung: Der Mechanismus ist einfach, aber nützlich

Natürlich können Sie es auch als Methodenreferenz übergeben, sodass Sie es so aufrufen können

Gewöhnliches Beispiel.java


stream.flatMap(Try(this::calc, (x,y)->Stream.empty()));

Wenn es die Funktion <T, R> akzeptiert, auch wenn es kein Stream ist, kann es optional sein.

Optional.java


Optional<String> name = getName();
name.flatMap(Try( dao::getFindByName ,(x,y)->Optional.empty()));

Auch beim Übergeben von Lambda an die Schnittstelle

Homebrew-Schnittstelle.java


interface JisakuInterface{
	String Method(String Argument);
}

JisakuInterface m = str->"hoge";
JisakuInterface f = Try(str -> str+str,(x,y)->"b")::apply;

Wenn Sie sich auf die Methode beziehen, können Sie sie problemlos mit Lambda übergeben. groß.

Danach, als ich Oleoremonado gemacht habe

Monamodoki.java


// LogicalDeletable.of(null)So generieren Sie ein logisches Löschen mit.
LogicalDeletable<LegacyData> record = getRecord(); 
//Diejenigen, die bei der Konvertierung einen Fehler gemacht haben, werden als logische Löschung behandelt
record.map(Try(Legacy::legacyTransform)) , (error,record) -> null));

Sie können also Ausnahmen machen.

Ich kann mir kein Beispiel vorstellen (viertes Mal), aber da der ausgelöste Inhalt als Argument an onCatch übergeben wird, sollten alle Funktionen möglich sein, die mit normalem TryCatch ausgeführt werden können (außer try-with-resource).

Deshalb sollte jeder die Ausnahme kühl abfangen.

[^ 1]: Qiita allein http://qiita.com/daylife/items/b977f4f29b1f8ced3a02, http://qiita.com/KIchiro/items/4fafd74c46d08275eb56, http://qiita.com/yoshi389111/items/c6b7f7

Recommended Posts

So behandeln Sie Ausnahmen mit Java 8 Stream oder Optional kühl
Behandeln Sie Ausnahmen kühl mit Java 8-Lambda-Ausdrücken und der Stream-API
Verwendung von Java Optional
So kompilieren Sie Java mit VsCode & Ant
[java] Zusammenfassung des Umgangs mit char
So debuggen Sie Java 9 oder höher remote
So behandeln Sie Anmeldefehler mit devise
[Java] Erfahren Sie, wie Sie Optional richtig verwenden
Java 9 Optional :: stream
Java8 / 9-Anfänger: Streamen Sie API-Suchtpunkte und wie Sie damit umgehen
[Java] So testen Sie, ob es in JUnit null ist
[java] Zusammenfassung des Umgangs mit Zeichenketten
Verwendung des Java-Frameworks mit AWS Lambda! ??
Verwendung der Java-API mit Lambda-Ausdrücken
Vorgehensweise optional in Protokollpuffern (proto3)
So vermeiden Sie Ausnahmen mit der Java-Methode equals
Aufrufen von Funktionen in großen Mengen mit Java Reflection
Listenverarbeitung zum Verstehen mit Bildern --java8 stream / javaslang-
[Java] So lassen Sie die Federkonstruktorinjektion mit Lombok weg
So stellen Sie Java mit Serverless Framework für AWS Lambda bereit
[Für Anfänger] So bedienen Sie die Stream-API nach Java 8
[Java] Verschlüsselung mit AES-Verschlüsselung mit Standardbibliothek
So konvertieren Sie A in a und a in A mit logischem Produkt und Summe in Java
So erstellen Sie eine Java-Entwicklungsumgebung mit VS Code
[Java] So unterbrechen Sie eine Zeile mit StringBuilder
So senken Sie die Java-Version
[Java] Verwendung von Map
So kehren Sie die Kompilierung der Apk-Datei in Java-Quellcode mit MAC um
Schreiben Sie Java Try-Catch mit Optional neu
So deinstallieren Sie Java 8 (Mac)
Verwendung des mit Tensorflow 2.0 trainierten Modells mit Kotlin / Java
Java zum Spielen mit Function
Java - So erstellen Sie JTable
Umgang mit hochgeladenen Bildern
[Ein Muss für einen Java-Ingenieurlehrling] Verwendung der Stream-API
So minimieren Sie Java-Images
Wie schreibe ich einen Java-Kommentar
Verwendung der Java-Klasse
[CQ Engine] Ich möchte Sammlungen wie Stream oder .Net LINQ auch in Java 7 verarbeiten.
[Java] Verwendung von removeAll ()
[Java] So zeigen Sie Wingdings an
Wie man mit html.erb nummeriert (nummeriert)
Verwendung von Java Map
So aktualisieren Sie mit activerecord-import
So legen Sie Java-Konstanten fest
Stellen Sie mit Java eine Verbindung zur Datenbank her
Stellen Sie mit Java eine Verbindung zu MySQL 8 her
Listenverarbeitung zum Verstehen mit Bildern --java8 stream / javaslang --bonus
So installieren Sie Java9 unter ElementaryOS Freya oder Ubuntu 14.04 LTS
Verwendung von Java-Variablen
[Java] Einführung in die Stream-API
Java8 startet jetzt ~ Optional ~
Umgang mit Instanzen
Unterschiede im Umgang mit Zeichenfolgen zwischen Java und Perl
So konvertieren Sie Java Base
[Java] So implementieren Sie Multithreading