簡易版 Java8 Stream API の編集履歴

tt が 2017-10-22 21:08 に編集

--- Ver.3	2017-10-21 03:02:24+09:00
+++ Ver.4	2017-10-22 21:08:12+09:00
@@ -21,11 +21,11 @@
 並列化はばっさり切捨てることにした.
 
 もう一つ, Java にはオブジェクトならぬプリミティブ型というものがあって,
-本物の Stream は IntStream だの何だのと, やたらごちゃごちゃしている.
+本物の Stream は `IntStream` だの何だのと, やたらごちゃごちゃしている.
 煩雑なのは嫌なので, プリミティブは一切合切捨ててしまおう.
 ラッパークラスのおかげで, あまり困らないはず.
 
-プリミティブは捨てるので, Predicate も Function で代用することにする.
+プリミティブは捨てるので, `Predicate` も `Function` で代用することにする.
 
 基本的なアイディアは,
 
@@ -45,15 +45,15 @@
 
 # 簡易ストリームの生成
 
-本物の Stream は, コンテナの stream()
+本物の Stream は, コンテナの `stream()`
 メソッドなどを通じて生成することが多いが,
 標準 API を書換えるわけには行かないので,
-専ら Stream インタフェースの static
+専ら `Stream` インタフェースの static
 なメソッドで生成することにした.
 
 ## iterate
 
-まずは iterate.
+まずは `iterate`.
 
 Stream.java が巨大になるのを避けるため,
 実装は別クラスに飛ばすことにする.
@@ -128,14 +128,14 @@
 ```
 
 `iterate` の実装は簡単である.
-iterate は終端がないので, 常に同じ操作を行うだけ.
+`iterate` は終端がないので, 常に同じ操作を行うだけ.
 
 この調子でどんどん書いて行ってみよう.
 
 ## of(Iterable<T>)
 
-前述の通り, List#stream などで生成するわけには行かないので,
-代わりに Stream#of を用意する. ついでに要素を列挙する of
+前述の通り, `List#stream` などで生成するわけには行かないので,
+代わりに `Stream#of` を用意する. ついでに要素を列挙する `of`
 も用意する.
 
 Stream.java(一部):
@@ -205,8 +205,8 @@
 
 ## limit
 
-iterate を用意したので, 簡単に終わらせることができるように
-limit をまず書いてみる.
+`iterate` を用意したので, 簡単に終わらせることができるように
+`limit` をまず書いてみる.
 
 Stream.java(一部):
 
@@ -325,8 +325,8 @@
   }
 ```
 
-Limit の実装のところで「前段の…」と述べた舌の根が乾かないうちに,
-Skip の実装は手抜きである.
+`Limit` の実装のところで「前段の…」と述べた舌の根が乾かないうちに,
+`Skip` の実装は手抜きである.
 `size == -1` で表現するなどすればよいだけだが,
 あんまり if 文を書きたくないので...
 
@@ -387,8 +387,8 @@
   }
 ```
 
-Java9 には Optional#ifPresentOrElse が導入されて便利になったそうだが,
-これに頼らず Optional#map を使って何とかするのが硬派.
+Java9 には `Optional#ifPresentOrElse` が導入されて便利になったそうだが,
+これに頼らず `Optional#map` を使って何とかするのが硬派.
 
 ## map
 
@@ -523,7 +523,7 @@
 
 ## collect
 
-なんだかんだ言って, 結局 `Stream` の最終結果を `Collection`
+なんだかんだ言って, 結局 Stream の最終結果を `Collection`
 に入れたくなったとき用の `collect` である.
 
 最初 Stream API のリファレンスを見たとき,
@@ -535,7 +535,7 @@
 それにしても「可変リダクション操作」という日本語はあまりにもひどいと思う.
 これ以上は本稿の主旨から外れるので解説は省く.
 
-本物の Collector インタフェースには, 並列化の機能が入り込んでいるので,
+本物の `Collector` インタフェースには, 並列化の機能が入り込んでいるので,
 その簡略版をまず用意する.
 
 Collector.java:
@@ -933,13 +933,13 @@
   }
 ```
 
-メソッド xr は, Exception を RuntimeException に変換する機能を持つ. (eXception to Runtimeexception で xr, ね)
+メソッド `xr` は, `Exception` を `RuntimeException` に変換する機能を持つ. (eXception to Runtimeexception で `xr`, ね)
 
 一見, 引数を取る関数が使えないので, 現場で使おうと思うと大量の関数インタフェースと,
-xr のオーバーロードを自作する羽目になるのでは,
+`xr` のオーバーロードを自作する羽目になるのでは,
 と心配する人もいるかもしれないが, それには及ばない.
 
-`x = someFunc(a)` の someFunc の例外宣言が嫌なら, `x = xr(() -> someFunc(a))` と書けばよいだけ.
+`x = someFunc(a)` の `someFunc` の例外宣言が嫌なら, `x = xr(() -> someFunc(a))` と書けばよいだけ.
 
 私自身, この技を仕事中にふと思いついて, 以来とても便利に多用している. お試しあれ.
 

tt が 2017-10-21 03:02 に編集

--- Ver.2	2017-10-21 03:00:14+09:00
+++ Ver.3	2017-10-21 03:02:24+09:00
@@ -935,7 +935,8 @@
 
 メソッド xr は, Exception を RuntimeException に変換する機能を持つ. (eXception to Runtimeexception で xr, ね)
 
-一見, 引数を取る関数が使えないので, 現場で使おうと思うと大量の関数インタフェースを自作する羽目になるのでは,
+一見, 引数を取る関数が使えないので, 現場で使おうと思うと大量の関数インタフェースと,
+xr のオーバーロードを自作する羽目になるのでは,
 と心配する人もいるかもしれないが, それには及ばない.
 
 `x = someFunc(a)` の someFunc の例外宣言が嫌なら, `x = xr(() -> someFunc(a))` と書けばよいだけ.

tt が 2017-10-21 03:00 に編集

--- Ver.1	2017-10-18 22:34:44+09:00
+++ Ver.2	2017-10-21 03:00:14+09:00
@@ -854,3 +854,91 @@
   }
 ```
 
+# おまけのおまけ
+
+Stream API は例外と相性が悪いと言う噂があるが,
+単に標準の関数インタフェースが throws 宣言をしていないことを指して文句を言っている人もいるようだ.
+
+その不満は, 自分で関数インタフェースを用意することで, ある程度解消することができると思う.
+
+例:
+
+```java
+package org.creasys.exp;
+
+import java.io.BufferedReader;
+import java.io.FileInputStream;
+import java.io.InputStreamReader;
+import java.nio.charset.StandardCharsets;
+
+public class Example
+  {
+	@FunctionalInterface
+	interface SupplierWithThrows<X>
+	  {
+		X get() throws Exception;
+	  }
+
+	@FunctionalInterface
+	interface RunnableWithThrows
+	  {
+		void run() throws Exception;
+	  }
+
+	private static <X> X xr(SupplierWithThrows<X> supplier)
+	  {
+		try
+		  {
+			return supplier.get();
+		  }
+		catch (Exception e)
+		  {
+			if (e instanceof RuntimeException)
+				throw (RuntimeException) e;
+			throw new RuntimeException(e);
+		  }
+	  }
+
+	private static void xr(RunnableWithThrows runnable)
+	  {
+		try
+		  {
+			runnable.run();
+		  }
+		catch (Exception e)
+		  {
+			if (e instanceof RuntimeException)
+				throw (RuntimeException) e;
+			throw new RuntimeException(e);
+		  }
+	  }
+
+	public static void main(String[] args)
+	  {
+		BufferedReader br = xr(() -> new BufferedReader(
+			new InputStreamReader(
+				new FileInputStream("foo.txt"),
+				StandardCharsets.UTF_8)));
+		try
+		  {
+			String line;
+			while ((line = xr(() -> br.readLine())) != null)
+				System.out.println(line);
+		  }
+		finally
+		  {
+			xr(() -> br.close());
+		  }
+	  }
+  }
+```
+
+メソッド xr は, Exception を RuntimeException に変換する機能を持つ. (eXception to Runtimeexception で xr, ね)
+
+一見, 引数を取る関数が使えないので, 現場で使おうと思うと大量の関数インタフェースを自作する羽目になるのでは,
+と心配する人もいるかもしれないが, それには及ばない.
+
+`x = someFunc(a)` の someFunc の例外宣言が嫌なら, `x = xr(() -> someFunc(a))` と書けばよいだけ.
+
+私自身, この技を仕事中にふと思いついて, 以来とても便利に多用している. お試しあれ.
+

tt が 2017-10-18 22:10 に投稿