Java8で難解コーディング 良いのか悪いのかわからない活用法

Java8の良いのか悪いのかわからない活用法を紹介します。
若干難解なので職場で活用して先輩に怒られても知りません。

#AutoCloseableってもしかして関数型インターフェース!??
AutoCloseableは@FunctionalInterfaceはもちろんついていませんが、
[関数型インターフェースの定義](http://www.ne.jp/asahi/hishidama/home/tech/java/functionalinterface.html#h_outline)からすれば関数型インターフェースですね。

つまり
##AutoCloseableでないクラスをtry-with-resourcesでクローズする
Graphicsなんかまさにdisposeめんどくさいですね。

```java
	/**
	 * 自力でGraphicsをclose
	 */
	public static void disposeSample(BufferedImage image) {
		Graphics graphics = image.createGraphics();
		try {
			//処理
		} finally {
			graphics.dispose();
		}
	}
```
簡単にはこうですが、場合によってはgraphicsのnull判定入れたりめんどくさいことこの上ないです。

ですがメソッド参照で

```java
	/**
	 * ラムダ式でAutoCloseable化。try-with-resourcesに。
	 */
	public static void disposeSample(BufferedImage image) {
		Graphics graphics = image.createGraphics();
		try (AutoCloseable closeable = graphics::dispose) {
			//処理
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
```

とするとtry-with-resourcesが使えるわけです
参考：[AutoCloseableでなくてもtry-with-resourcesがしたい](http://irof.hateblo.jp/entry/20130105/p1)

が、これだとExceptionをcatchしないといけないので

```java
	/**
	 * throwsなしのAutoCloseable
	 */
	public interface MyCloseable extends AutoCloseable {
		@Override
		void close();
	}

	/**
	 * catchが不要になった
	 */
	public static void disposeSample(BufferedImage image) {
		Graphics graphics = image.createGraphics();
		try (MyCloseable closeable = graphics::dispose) {
			//処理
		}
	}
```
とすれば完璧です！！MyCloseableを一つ作っておきましょう！


もう一段階難解にしたいなら下記のようにするのもおすすめです。

```java
	public static void disposeSample(BufferedImage image) {
		Graphics graphics;
		try (MyCloseable closeable = (graphics = image.createGraphics())::dispose) {
			//処理
		}
	}
```

#Iterableってもしかして関数型インターフェース!??
Iterableは@FunctionalInterfaceはもちろんついていませんが、
[関数型インターフェースの定義](http://www.ne.jp/asahi/hishidama/home/tech/java/functionalinterface.html#h_outline)からすれば関数型インターフェースですね。

つまり、
##Iteratorを拡張for文で回す

```java
	/**
	 * Iteratorを拡張for文で回す。
	 */
	public static void iteratorFor() {
		Iterator<String> iterator = Arrays.asList("A", "B", "C").iterator();//Iteratorを作りたいだけ。
		for (String s : (Iterable<String>) () -> iterator) {
			System.out.println(s);
		}
	}
```
とすると、Iteratorで拡張for文が使えるわけです！

もちろん今回の場合、普通はIterator#forEachRemainingを使って

```java
	/**
	 * 普通にIterator#forEachRemaining
	 */
	public static void iteratorFor() {
		Iterator<String> iterator = Arrays.asList("A", "B", "C").iterator();//Iteratorを作りたいだけ。
		iterator.forEachRemaining(System.out::println);
	}
```
とJavaさんからは推奨されそうですが、
この場合、**breakできない**のが玉に傷ですね。

```java
	/**
	 * Iteratorを拡張for文で回す。
	 */
	public static void iteratorFor() {
		Iterator<String> iterator = Arrays.asList("A", "B", "C").iterator();//Iteratorを作りたいだけ。
		for (String s : (Iterable<String>) () -> iterator) {
			if(s.equals("B"))
				break;
			System.out.println(s);
		}
	}
```
とかね。

##Listライクな情報からStream生成
これは難解コーディングではありませんが、次のテーマの下準備です。
sizeっぽい情報と、get(index)っぽいメソッドがあればStreamにすることができます。

```java
	/**
	 * StringBuilderをCharacterのListにする<br>
	 * 途中CharacterのStreamにしてる
	 */
	public static List<Character> stringBuilderToCharList() {
		StringBuilder sb = new StringBuilder("ABC");
		return IntStream.range(0, sb.length())
				.mapToObj(sb::charAt)
				.collect(Collectors.toList());
	}
```
参考：http://www.ne.jp/asahi/hishidama/home/tech/java/stream.html#h_outline
の例「Excelのシート一覧取得」

さあここから、
##Streamを拡張for文で回す（Listライクな情報を拡張for文で回す）
Streamからiterator()を呼び出してラムダ式でIterable化すれば拡張for文が使えます。

```java
	/**
	 * StringBuilderを拡張for文で回す。
	 */
	public static void stringBuilderFor() {
		StringBuilder sb = new StringBuilder("ABC");
		for (Character c : (Iterable<Character>) () -> IntStream.range(0, sb.length()).mapToObj(sb::charAt)
				.iterator()) {
			System.out.println(c);
		}
	}
```

もちろんStreamもforEachメソッド持ってるので通常はそちらを使うべきですが、**bre**（略）

でもでも、collect(Collectors.toList())したら普通に拡張for文使えますよね？
その通り。使えますが比較してみると大きな違いがあります。

```java:準備
	private static class ListLike {
		public int size() {
			return 10;
		}

		public String get(int index) {
			System.out.println("get(" + index + ")");
			return Integer.toString(index);
		}
	}
```

```java:iteratorから
	public static void iteratorFor() {
		System.out.println("iteratorFor");
		ListLike list = new ListLike();
		for (String s : (Iterable<String>) () -> IntStream.range(0, list.size())
				.mapToObj(list::get)
				.iterator()) {
			if(s.equals("4")){
				break;
			}
			System.out.println("each " + s);
		}
	}
```

```java:collectから
	public static void collectFor() {
		System.out.println("collectFor");
		ListLike list = new ListLike();
		for (String s : IntStream.range(0, list.size())
				.mapToObj(list::get)
				.collect(Collectors.toList())) {
			if(s.equals("4")){
				break;
			}
			System.out.println("each " + s);
		}
	}
```

実行結果はそれぞれ

* iteratorFor

>iteratorFor
>get(0)
>each 0
>get(1)
>each 1
>get(2)
>each 2
>get(3)
>each 3
>get(4)

* collectFor

>collectFor
>get(0)
>get(1)
>get(2)
>get(3)
>get(4)
>get(5)
>get(6)
>get(7)
>get(8)
>get(9)
>each 0
>each 1
>each 2
>each 3


となりcollectは一回リストにするのでその分無駄があります。
やはりIterableをラムダ式で生成するのがスマート(!?)ですね！

---

こちらもどうぞ
[Java8が好きになる話（StreamAPIの話はしない） その1 Map#computeIfAbsentとList#sort](http://qiita.com/ota-meshi/items/31f36d38d4da8fce3c57)
[Java8が好きになる話（StreamAPIの話はしない） その2 Optional#map](http://qiita.com/ota-meshi/items/dbdd592b613e38b7a4bb)
[Java8が好きになる話（StreamAPIの話はしない） その3 インターフェースのデフォルト実装](http://qiita.com/ota-meshi/items/43811647af9daed4d21e)
[Java8が好きになる話（StreamAPIの話はしない） その4 ラムダ式のインスタンス](http://qiita.com/ota-meshi/items/86e22b790d54819e2012)