Are you using the Java8 Streams API? It's very convenient. The Streams API, or lambda expression, is very powerful.
Lambda is very powerful but poorly illustrated.java
Function<String, String> slice = x -> x.substring(3, 6);
System.out.println(slice.apply("abcdefghij")); // -> "def"
As many have pointed out, [^ 1] is incompatible with exception handling, and exceptions cannot be caught outside of lambda. (No, I think it's natural because it's a lump of processing with lambda.)
In the above example, if the character string is 3 characters or less, an error will occur, so let's insert exception handling so that it will be returned as it is when an error occurs.
Try Catch is not cool and nesting is deep and I want you to stop.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, the nest is deep.
Also, in the case of a method that throws a checked exception, you have to try catch in the lambda, so you can not call hoge :: fuga that throws an exception with stream.map (hoge :: fuga), which makes you feel frustrated. .. If it is an unchecked exception, it can be retrieved at the timing of calling (try {stream.map (hoge :: fuga)} catch {~}), but it is not clean. There is also a library that wraps Stream and Optional, but it is relatively inconvenient.
I want to write the above example with one liner. If you pass two lambdas, the first lambda is normal processing, and the second lambda is exception handling, it will be smart. So, first of all, prepare a functional interface that throws an exception
Function that throws an exception.java
interface ThrowableFunction<T, R> {
R apply(T t) throws Exception;
}
And define Try like this
The whole picture is coming into view.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);
}
};
}
That alone allows for cool coding!
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"
If the Consumer does the same,
For Consumer.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);
}
};
}
This is also cool!
I did it.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"・ ・ ・
The good thing about this method
Bad place
Of course, you can also pass it as a method reference, so you can call it like this
Ordinary example.java
stream.flatMap(Try(this::calc, (x,y)->Stream.empty()));
If it accepts Function <T, R> even if it is not Stream, it can be Optional.
Optional.java
Optional<String> name = getName();
name.flatMap(Try( dao::getFindByName ,(x,y)->Optional.empty()));
Also when passing lambda to the interface
Homebrew interface.java
interface JisakuInterface{
String Method(String Argument);
}
JisakuInterface m = str->"hoge";
JisakuInterface f = Try(str -> str+str,(x,y)->"b")::apply;
If you refer to the method, you can easily pass it with lambda. great.
And when I made oleore monads,
Monamodoki.java
// LogicalDeletable.of(null)To generate a logical delete with.
LogicalDeletable<LegacyData> record = getRecord();
//Those who made a mistake in conversion are treated as logical deletion
record.map(Try(Legacy::legacyTransform)) , (error,record) -> null));
So you can take exceptions.
I can't think of an example (4th time), but since the thrown content is passed to onCatch as an argument, all the functions that can be done with normal TryCatch should be possible (except for try-with-resource).
That's why everyone should catch the exception coolly.
[^ 1]: Qiita alone http://qiita.com/daylife/items/b977f4f29b1f8ced3a02, http://qiita.com/KIchiro/items/4fafd74c46d08275eb56, http://qiita.com/yoshi389111/items/c6b7d373a00f8fd3
Recommended Posts