読書会(Javaによる関数型プログラミング)第1回議事録
[ 戻る ]
==============================================================
Java読書会BOF 「Javaによる関数型プログラミング」を読む会 第1回
==============================================================
.. csv-table:: 開催概要
"日時","2016年9月24日 10:00 - 17:00"
"場所","川崎市教育文化会館 第3会議室"
"出席者(敬称略)","高橋(徹)、遠藤、高田、吉本, 平山, 加藤、井上、川内、青山、松永、小棚木、吉田、岩室(書記)"
著者紹介/訳者紹介/レビュア紹介
============================================================
* 厳密には「JavaSE」⇒「Java SE」
* 日本唯一 ⇒ てらだよしおさんが2人目のJava Championになった。
日本語版まえがき
============================================================
* p.v
* 「対象としていたの」⇒「対象としていたのは」
* J2SEは1.4までではなく5まで。
まえがき
============================================================
はじめに
============================================================
* 書籍WebページのURLミス。
* ×「http://www.oreilly.co.jp/9784873117041」
* ○「https://www.oreilly.co.jp/books/9784873117041/」
1章 Hello、ラムダ式!
============================================================
1.1 考え方を変える
------------------------------------------------------------
1.1.1 従来の方法
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.1.2 より良い方法
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.1.3 具体的な改善ポイント
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.1.4 シンプルな場合を超えて
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.1.5 もう一度、従来の方法
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 「プリミティブ型への執着」の意味がわからない。
* 「単一責任の原則を無視しています」の意味がわからない。
* 「フィルタ」「割引」「総和」の処理がまとめてひとつになっているからと思われる。
* p.4 L.6 「20ドル以上の場合」⇒「20ドルを超える場合」
1.1.6 もう一度、より良い方法
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.1.7 改善ポイント
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 「大幅に改善されました」と書かれているが:
* 改善前が簡単な内容なので、より良くなったと思えない。
* 抽象的過ぎてかえってわかりづらくなっていないか。
* この例を見せられても挫折しそう。
* 「reduce」の意味がわかりにくい。⇒「集約」の意味。
1.1.8 ラムダ式が救う
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* p.6 「開発者を開放する」⇒「開発者を【開放】する」
1.2 関数型のコードによる大きな利益
------------------------------------------------------------
* p.7 3つ目の「・」⇒「新しいリストを生成し」というのは正しいのか?
* 考え方としては間違っていないが、厳密には正しくない。実際にListのオブジェクトが生成されるわけではない。
1.3 なぜ関数型で記述するのか
------------------------------------------------------------
1.3.1 強化されたイテレータ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.3.2 ポリシーの強制
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* このような使い方が一番恩恵が高いのではないか。
* 従来だとテンプレートパターンで書いていたが、テンプレートパターンだと柔軟性が低い。
1.3.3 ポリシーの拡張
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.3.4 混乱のないコンカレンシー
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.3.5 物語を語る
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.3.6 関心の分離
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.3.7 評価を遅らせる
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.3.8 テスト環境の向上
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Java8用ユニットテストフレームワークはあるか? ⇒ 宿題
* JUnit5は対応しているが、まだ正式リリースされていない。
* モックがlambda対応だと便利そう。
1.4 革命でなく、進化
------------------------------------------------------------
1.4.1 宣言的になる
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.4.2 不変性を尊重する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* p.16 「Joshua Block」⇒「Joshua Bloc【h】」
* Arrays.asList() は不変ではない。
* 配列をラップする Arrays.ArrayList が使われる。
* set() は使えるが add() は使えない。Listインターフェースを持つ配列と考えると良い。
1.4.3 副作用を避ける
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.4.4 文より式を優先する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1.4.5 高階関数を使って設計する
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 「関数を生成する」とは?
* 無名クラスの生成とほぼ同等と考えればよい。
* 実際にはJVMによりいろいろな最適化がなされる。
1.5 簡単にするためのほんの少しの砂糖
------------------------------------------------------------
1.6 まとめ
------------------------------------------------------------
2章 コレクションの使用
============================================================
2.1 リストをイテレート
------------------------------------------------------------
* p.28 例2-7 「System.out.println」⇒「System.out【::】println」
* インスタンスメソッドでもメソッド参照にすることが可能。
2.2 リストの変換
------------------------------------------------------------
* p.29 例2-9 「System.out.println」の前で改行すべき。
* 「forEachを使うと負け」
2.2.1 ラムダ式を使う
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 例2-9と例2-10で出力の表現形式が微妙に異なる。例2-8にいたっては出力されていない。
* map()の返り値はStreamであってCollectionではないのでは?
* Javaの型のCollectionではなく、日本語のコレクション(集まり)では。
* 原書のエラッタではCollectionではないと指摘されている。
* p.30 例2-11 forEachにおけるlambdaの引数名がnameなのは不適切では?
* サンプルコードでは「count」になっている。
2.2.2 メソッド参照を使用
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* p.31 例2-12 forEachの部分もメソッド参照にできるのではないのか?
* (同上) 出力形式が変わっていないか?
* p.31 以下はカギカッコでくくる必要がある。
* メソッド参照はいつ使うべきかを参照してください。
* ⇒ 「メソッド参照はいつ使うべきか」を参照してください。
* lamda式とメソッド参照はどちらが良いか?
* IntelliJではメソッド参照に書き換え可能な場合は指摘してくれる。
* String::toUpperCaseの場合は引数をレシーバにしてtoUpperCase()を呼び出すが、System.out::printlnの場合は引数として渡される。このような違いはわかりづらいのではないか。
2.3 要素の検索
------------------------------------------------------------
* stream処理の返り値に関する表記がばらばら(コレクションだったりStreamだったりイテレータだったり)だが、中間操作の返り値は全てStream。
* Streamは順序は維持されるか?
* 順序付けされているStreamとされていないStreamがある。
* parallelStreamでは基本的に維持されない。
2.4 ラムダ式の再利用
------------------------------------------------------------
* p.34 「ある文字で始まる名前だけを抽出します」⇒「ある文字で始まる名前の数を抽出します」
2.5 静的スコープとクロージャ
------------------------------------------------------------
2.5.1 ラムダ式における重複
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2.5.2 静的スコープで重複排除
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2.5.3 スコープを限定するようにリファクタリング
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2.6 要素を1つ選択
------------------------------------------------------------
* p.41 例2-25 「A name starting with ...」の「A」は冠詞。
* やっぱり「プリミティブ型への執着」の意味がわからない。
2.7 コレクションを単一の値に集約 (reduce)
------------------------------------------------------------
* 例2-31 "Steve"は単位元ではないので、この例ではかまわないが、バグの要因になるのではないか。
* 引数が1つのreduceはどのように処理されるのか?
* streamの要素が空のときはOptional.empty()、1つのときはそのまま、2つ以上のときに引数のlambdaが呼ばれる。
* 引数の型はBinaryOperator<T>なので、処理結果の型をstreamの型と異なるものにはできない。
* 処理結果の型を異なるものにする場合は3引数のreduce()を用いる。
2.8 要素の結合
------------------------------------------------------------
* p.47 例2-33 普通はこのような書き方はしないのではないか。よくある書き方の例を以下に示す::
// https://twitter.com/quiver2k/status/779576208761643008
String delim = "";
for (String name : friends) {
System.out.print(delim + name);
delim = ", ";
}
* p.48 例2-35 joining()をクラス名無しで使えるのか?
Collectors を static imoprt していると思われる。
2.9 まとめ
------------------------------------------------------------
3章 文字列、コンパレータ、フィルタ
============================================================
3.1 文字列のイテレーション
------------------------------------------------------------
* p.52 「Integerのストリーム」⇒「IntStream」
* p.53 訳注 「char()」⇒「chars()」
* p.53 例3-3 サンプルコードによると、メソッド名は「printchars」⇒「printChar」
* p.54 例3-6 サンプルコードによると、メソッド名は「printchars」⇒「printChar」
* p.54 「filter()メソッドと、foreach()」⇒「filter()メソッドと、foreach()メソッド」
3.2 Comparatorインターフェースを実装
------------------------------------------------------------
3.2.1 コンパレータを使ったソート
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* p.56 「生成」⇒「作成」の方がよいのでは。
* メソッド参照を使い過ぎるのはどうか?
* sortedくらいなら問題はないのではないか。
* コンパイラがいろいろやっているということは、人間がコンパイラのエミュレーションをしないと理解できない可能性がある。
3.2.2 コンパレータの再利用
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* 次回は p.62 の先頭から。
(以上)
[ 戻る ]