commons-lang3のFailableが便利

# 先にまとめ
Java8で登場したLambda式を使うと、例外処理が煩雑になりがちだけど、[Apache Commons Lang3](https://commons.apache.org/proper/commons-lang/)(3.11以降)のFailableを使用すると以下のようにスッキリ書ける。

## 使用前

```java
private static void deleteFiles(List<Path> paths) throws IOException {
    for (Path path : paths) {
        Files.deleteIfExists(path);
    }
}
```

## 使用後

```java
private static void deleteFiles(List<Path> paths) throws IOException {
    paths.forEach(Failable.asConsumer(Files::deleteIfExists));
}
```
以下、ここに至る経緯。読み飛ばし可。

# Streamを使うと途端に例外処理が面倒になるよね
Java8でLambda式が登場し、コードがなんかカッコよく書けるようになった。早速自分もLambdaしてみよう！モダンなプログラマーっぽくなろう！とやってみると、例外処理でハマる。

```java
private static void deleteFiles(List<Path> paths) throws IOException {
    for (Path path : paths) {
        Files.deleteIfExists(path);
    }
}
```
これをLambdaで書いてみる。

```java
private static void deleteFiles(List<Path> paths) throws IOException {
    paths.forEach(Files::deleteIfExists);
}
```

すると、`Files.deleteIfExists`がthrowする`IOException`が処理されない、とコンパイルエラーになってしまう。よく見ると`Consumer.accept`にはthrows定義が無いので当然ではある。
従ってこれを以下のように`try-catch`で`IOException`をハンドルする必要がある。しかし、これでは発生した`IOException`をメソッドの呼び出し元にthrowするというインターフェイスを崩してしまうことになる。(またなにより、Lambdaを使ってカッコよく、という当初の目的が達せられず、レガシーなJavaおじさんに戻ってしまうことになる。)

```java
private static void deleteFiles(List<Path> paths) throws IOException {
    paths.forEach(t -> {
        try {
            Files.deleteIfExists(t);
        } catch (IOException e) {
            // handle e
        }
    });
}
```

ちなみに、インターフェイスを崩さないよう発生例外を送出するにはこのような実装が必要になり、レガシーJavaおじさんどころか、退化してしまっているんではないかと思われる。

```java
private static void deleteFiles(List<Path> paths) throws IOException {
    try {
        paths.forEach(t -> {
            try {
                Files.deleteIfExists(t);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        });
    } catch (UncheckedIOException e) {
        throw e.getCause();
    }
}
```

# 解決
世の中のみなさんはどうしているのだろう、と調べていたら、こんな事例が。
(ネタ元が見当たらない。海外の人の投稿だったと記憶。ConsumerではなくFunctionの例だったかも。)

```java
public class RethrowFunctions {
    @FunctionalInterface
    public interface ConsumerWithExceptions<T, E extends Exception> {
        void accept(T t) throws E;
    }

    public static <T, E extends Exception> Consumer<T>
            rethrowConsumer(ConsumerWithExceptions<T, E> consumer) throws E {
       return t -> {
            try {
                consumer.accept(t);
            } catch (Exception exception) { // CS:IGNORE Exceptionのcatchは仕方ない
                throwAsUnchecked(exception);
            }
        };
    }

    private static <E extends Throwable> void throwAsUnchecked(Exception exception) throws E {
        throw (E) exception;
    }
```

これを使うと、以下のように書ける。これならインターフェイスも崩さず、そしてシンプル！

```java
private static void deleteFiles(List<Path> paths) throws IOException {
    paths.forEach(RethrowFunctions.rethrowConsumer(Files::deleteIfExists));
}
```

という訳で同様の実装を以下のFunctionalInterfaceに対しても実装し、そのjavaファイルを必要なプロジェクトに配って回ったのである。
(配布方法がイマイチではあるが、いろいろと制約事項があり。)

* java.lang.Runnable
* java.util.function.Function
* java.util.function.Predicate
* java.util.function.Supplier
* java.util.function.BiConsumer
* java.util.function.BiFunction
* java.util.function.BiPredicate

# 解決、その後
ある日、commons-lang3に`Failable`というものを発見。もしや？！と思ってみてみると、まさに前述の`RethrowFunctions`と同じことを実現するものであった。commons-lang3であればすでに様々なプロジェクトで使用しているし汎用的なものなので、これからは自作javaファイルを配らずこちらを使うことにしよう。

というわけで、commons-lang3の`Failable`おすすめ。