stream中にエラーハンドリングできなくてこまるやつ

##例外catchしてくださいって怒られるやつ

ぐぬぬ一行で書けない...

っていうのをどうにか綺麗に書くためのやつです


##準備
```準備.java
	/** --------------------準備-------------------- */
	/** 例外を投げるインターフェース */
	private static interface Throwable<T, S> {
		S apply(T t) throws NullPointerException, NumberFormatException, Exception;
	}
	/** 例外に応じて実行する関数を切り替えるメソッド */
	private static <T, S> Function<T, S> switchFunction(Throwable<T, S> tf, BiFunction<Exception, T, S> npe,
			BiFunction<Exception, T, S> nfe, Function<Exception, S> other) {
		return v -> {
			try {
				return tf.apply(v);
			} catch (NullPointerException e) {
				return npe.apply(e, v);
			} catch (NumberFormatException e) {
				return nfe.apply(e, v);
			} catch (Exception e) {
				return other.apply(e);
			}
		};
	}
```

例外を投げられるFunctionを作りまして
とあるFunctionを実行しようとしたときに例外がでたらこっちのFunctionにするーっていうメソッドを作ります

<ul>
<li>やりたい処理
<li>ぬるぽならこの処理
<li>NumberFormatExceptionならこの処理
<li>その他ならこの処理
</ul>

の4つを実装していきます

##内部の処理の実装
```内部.java
	/** --------------------具体的な処理の実装-------------------- */
	/** メイン処理 */
	private static final Throwable<String, Integer> tf = v -> {
		if (v.equals("5")) {
			return Integer.parseInt(v);
		} else if (v.equals("999")) {
			throw new NullPointerException();
		} else if (v.equals("ddd")){
			throw new NumberFormatException();
		} else {
			throw new IOException();
		}
	};
	/** ぬるぽの時の処理 */
	private static final BiFunction<Exception, String, Integer> npe = (e, v) -> {
		e.printStackTrace();
		return 0;
	};
	/** 数値変換だめなときの処理 */
	private static final BiFunction<Exception, String, Integer> nfe = (e, v) -> {
		e.printStackTrace();
		return v.length();
	};
	/** その他の例外時の処理 */
	private static final Function<Exception, Integer> other = e -> {
		e.printStackTrace();
		return 1;
	};
```

今回は全パターンみたいので強制的にException投げるようにしました
それじゃ実行していきましょう

##実行
```実行.java
	/** --------------------実行-------------------- */
	public static void main(String[] args) {
		Arrays.asList("5", "ddd", "999", "0").stream().map(switchFunction(tf, npe, nfe, other))
				.forEach(System.out::println);
	}
```

```結果
5
java.lang.NumberFormatException
	at test1.Test1.lambda$0(Test1.java:35)
	at test1.Test1.lambda$4(Test1.java:18)
	at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at test1.Test1.main(Test1.java:55)
3
java.lang.NullPointerException
	at test1.Test1.lambda$0(Test1.java:33)
	at test1.Test1.lambda$4(Test1.java:18)
	at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at test1.Test1.main(Test1.java:55)
0
java.io.IOException
	at test1.Test1.lambda$0(Test1.java:37)
	at test1.Test1.lambda$4(Test1.java:18)
	at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
	at java.util.Spliterators$ArraySpliterator.forEachRemaining(Unknown Source)
	at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
	at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
	at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
	at java.util.stream.ReferencePipeline.forEach(Unknown Source)
	at test1.Test1.main(Test1.java:55)
1

```

想定通りですね

##弱点
まぁ見てわかる通り、実装できるFunctionの引数、戻り値の型が
せっかくジェネリクスでとってるのに、全部一致してないとダメってことですね

現実的な実装だと困るケースも出てきそうです
っていうかこんなにFunction重ねるとなんか重くなりそうです...いいのかこれ

実行部分、内部の処理が綺麗に分かれているので
可読性はめっちゃ高いんじゃないでしょうか
けどね、うん　準備長すぎな

一連のstreamに対する中間操作でどうしてもExceptionを吐くケースが複数あるなら
こういった実装をした方がきれいにまとまるとかありそうです

##これをメソッドでやってみる
```これでしょ.java
public class Test7 {
	private static <T>void switchMethod(T t) {
		try {
			s1(t);
		} catch (NumberFormatException e) {
			s2(t);
		}
	}
	private static <T>void s1(T t) throws NumberFormatException{
		System.out.println(Integer.parseInt((String) t));
	}
	private static <T>void s2(T t) {
		System.out.println(t + "すうちむり");
	}
	public static void main(String[] args) {
		List<String> list = new ArrayList<>(Arrays.asList("a", null, "2"));
		list.stream().forEachOrdered(Test7::switchMethod);
	}
}
```

```
aすうちむり
nullすうちむり
2
```

やっぱ準備段階でメソッドは増えまくるんですよねぇ


例外吐いた場合の挙動が同じなら使った方が綺麗ですけども...


うーむ、難しい...