Что делать, если каждому функциональному интерфейсу, предоставленному java.util.function
, разрешено генерировать исключение?
public interface ThrowingSupplier {
public R get() throws X;
}
Мы могли бы использовать некоторые методы по умолчанию для обеспечения желаемого поведения.
Я написал библиотеку , которая переопределяет большинство интерфейсов в java.util.function
таким образом. Я даже предоставляю ThrowingStream
, который позволит вам использовать эти новые интерфейсы с тем же API, что и обычный Stream
.
@FunctionalInterface
public interface ThrowingSupplier {
public R get() throws X;
default public Supplier fallbackTo(Supplier extends R> supplier) {
ThrowingSupplier t = supplier::get;
return orTry(t)::get;
}
default public ThrowingSupplier orTry(
ThrowingSupplier extends R, ? extends Y> supplier) {
Objects.requireNonNull(supplier, "supplier");
return () -> {
try {
return get();
} catch (Throwable x) {
try {
return supplier.get();
} catch (Throwable y) {
y.addSuppressed(x);
throw y;
}
}
};
}
}
( Nothing
- это RuntimeException
, который никогда не может быть брошен.)
Ваш исходный пример станет
ThrowingFunction parse = Integer::parseInt;
Function> safeParse = parse.fallbackTo(s -> null)
.andThen(Optional::ofNullable);
Stream.of(s1, s2)
.map(safeParse)
.map(i -> i.orElse(-1))
.forEach(System.out::println);