昨日に引き続き。今日は「きつねさんと学ぶLambda式&StreamAPIハンズオン」の方。
【Date and Time API】Java 8徹底再入門【ラムダ式ハンズオン】(大阪,7/11) - connpass
全然難しく感じなかったので。すごいなーと思いました。
順を追って丁寧にワンステップずつ進めてくれました。
そこのハンズオンやっている人、どこからどう見ても学生チューターにしか見えないが、実はLambdaにも若干絡んでいる最年少JDKコミッタというとんでもない大物である。 #kanjava
— HASUNUMA Kenji (@khasunuma) 2015, 7月 11
ハンズオン用のコードはこれ
bitter_fox / Lambda — Bitbucket
です。
ステップ1 Lambda式の書き方
これを。。。
Runnable r = new Runnable() { @Override public void run() { System.out.println("HelloWorld!"); } };
こうする!
Runnable r = () -> System.out.println("HelloWorld!");
ちゃんとは覚えてないんだけど、一歩ずつ教えてくれたので、するっとできた。
- Runnableクラスだって分かってるから省略しても大丈夫だよね?
- メソッドは一個しかないんだから、省略しても分かるよね?
- 1行だから波括弧なくてもいいよね?
- ほらね、怖くない。ね?怯えていただけなんだよね。
大体そんな感じ。
ステップ2 引数ある場合、戻り値ある場合
引数が1つある場合
ステップ1では引数も戻り値もなかったけど、次は引数がある場合
Consumer<Integer> con = new Consumer<Integer>() { @Override public void accept(Integer t) { System.out.println(t); } }; con.accept(10);
↓↓↓
Consumer<Integer> con = t -> System.out.println(t); con.accept(10);
引数が1個だったら引数のところの丸括弧が省略できることを理解。
戻り値がある場合
Predicate<Integer> isEven = new Predicate<Integer>() { @Override public boolean test(Integer t) { return t % 2 == 0; } }; System.out.println(isEven.test(10));
↓↓↓
Predicate<Integer> isEven = t -> t % 2 == 0; System.out.println(isEven.test(10));
1行ならreturn書かなくてイイことを理解。
引数が2つの場合
BiConsumer<Integer, Integer> biCon = new BiConsumer<Integer, Integer>() { @Override public void accept(Integer n, Integer m) { System.out.println(n + " + " + m + "=" + (n + m)); } }; biCon.accept(10, 20);
↓↓↓
BiConsumer<Integer, Integer> biCon = (n, m) -> System.out.println(n + " + " + m + " = " + (n + m)); biCon.accept(10, 20);
引数が2つ以上ある場合は、丸括弧が必要なことを理解した!
という感じで
丁寧に1ステップずつ教えてくれたんですね。
関数型インターフェースについて
- 関数型インターフェースを自分で作ってみて!
- FunctionalInterfaceアノテーションについて
forEach
- for-eachをラムダ式を用いて書いてみよう
filter
- 条件で要素への操作を除外する
map
- 要素を別の要素に変化させて処理をしてみよう
reduce/sum/summaryStatistics
- 総和を求めてみる
- IntStreamに対して
- reduceを使ってみて!
- sumを使ってみて!
- summaryStatisticsを使ってみて!
- IntStreamに対して
average/Optional
- 平均値を求めてみる
- averageを使ってみて!
- とここでOptionalについて
- summaryStatisticsを使ってみて!
- averageを使ってみて!
collect
- "{"とか"}"で終わる行だけのリストを返してみて!(filterからのcollect)
- この辺でCollectorsについての説明
flatMap
- すべての会社の自動車のうち,軽自動車(排気量が660cc以下)の名前のリストを取得
- 会社が車のリストを持ってるから、company.streamからのflatMapで自動車リストにしちゃう
Collectors.joining
- 名前を「, 」区切りで連結して!
- Collectors.joining
- peopleの名前を「, 」区切り,[]囲みで連結してみて!
return people.stream() .map(p -> p.getName()) .collect(Collectors.joining(", ", "[", "]"));
Collectors.groupingBy
- 苗字(LastName)ごとのPeopleの名前(FirstName)のリストを作って!
return people.stream() .collect(Collectors.groupingBy(p -> p.getLastName(), Collectors.mapping(p -> p.getFirstName(), Collectors.toList())));
ちがう!そうじゃないんや! > {小林=[小林, 小林], 田中=[田中, 田中, 田中, 田中], 山田=[山田, 山田, 山田], 吉田=[吉田]} #kanjava
— Elastic bufferings (@bufferings) 2015, 7月 11
まとめ
頭で理解するだけじゃなくて、手を動かして理解できた!!楽しかったー。
個人的に気になった部分
その1
IntelliJって、こういうとき、文字列順じゃなくて、数字順でソートしてくれるんね。なんか素敵。
その2
//<editor-fold defaultstate="collapsed" desc="bootstrap">
なんぞこれ!?折りたたまれる!!
つーか、伝えたい部分だけを表示してくれてるきつねさんの心遣いがステキすなー。