JJUG CCC 2018 Fallに参加してきました。
@skrb さんの#ccc_g4の講演内容を個人的にまとめました。
Streamってなに?
Streamは単純なイテレータである
- イテレータは2種類存在する。
- 外部イテレータ
- 繰り返しの制御を自分で記述
- for 拡張for iteratorクラス
- for文のループ部はもちろん、get(x)の部分も制御部分である。
- 複雑
- 記述力はそれほどでもない。
- 内部イテレータ
- 繰り返しはライブラリ任せ(Stream API)
- シンプル
- 記述力高い。
- 外部イテレータ
ラムダ式の立ち位置
蝶のように舞い、鉢のように刺すのがモハメド・アリ
関数のように記述し、クラスのように振る舞うのがラムダ式
関数<============ラムダ式============>クラス
処理 関数のように記述し 状態+処理
クラスのように振る舞う
Streamはなぜわからないのか?
一度試したけどわからなかった人多数
新しい技術があったら・・・
- まず使ってみるか?
- 完全に理解するまで使わないか?
例:オムレツを作るのに、タンパク質の熱変性は60度で、メイラード反応というのがあって・・・
と知ってても、そんなこと気にせず作りますよね??
新しい概念だからこそ、習うより慣れよ。 かけるようになってから仕組みを理解すればよい。
Stream = データの流れ
ループより、加工して処理するものだと考える。
加工するのに、クラス作ったりしたくない。
→ ラムダ式 引数と返り値だけを決めた処理の記述法
(引数)->{
toDO
return val;
}
結局Streamはなんなのか
やりたいことをデータの加工という観点で組み立て直す。
工程をシンプル化し、1工程 -> シンプルな4工程にわける -> 最終的にtoList()などで箱詰め。
まずはfor eachからはじめて、徐々にmap->filter等やってみるのが吉
よく使われるラムダ式
1引数 返り値あり Function
1引数 返り値boolean Predicate
1引数 返り値なし Consumer
引数なし 返り値あり Supplier
基本的な書き方
// 基本的なやつ
(String s) -> { return s.length();
// 型は省略可能
(s) -> { return s.length();
// 1行なら returnも省略可能
(s) -> s.length();
// 1引数なら ()も省略可能
s -> s.length();
こんなの覚えなくてもIDEがやってくれる。
最低限覚えておけば良いパターン
- データを加工する中間の処理。
- データを取捨選択する
- filter
- dropWhile ※1引数 返り値boolean
- takeWhile
- データを加工する。
- map ※1引数 返り値あり
- flatmap ※1引数 返り値 Stream ←入れ子のstreamとか出てきたときに使う。1次元に変換
- データを纏める最後の処理。
- 探す
- findFirst 単一データの返却
- findAny 単一データの返却 ※ラムダ式なし
- anyMatch 正規表現探索
- allMatch 正規表現探索
- oneMatch 正規表現探索 ※1引数 返り値 boolean
- まとめる
- collect ※Collectors::staticメソッド
- toList ※ラムダ式なし
- groupingBy ※1引数 返り値あり(map)
- 逐次処理
- for-each 1引数 返り値なし
- 探す
- データを取捨選択する
例: Listから、小文字のaで始まる単語を抜き出す。
List<String> words = new ArrayList<>() {
{
add("apple");
add("toast");
add("about");
add("sun");
}
};
var results = words.stream()
.map(word -> word.toLowerCase())
.filter(word -> word.startsWith("a"))
.collect(Collectors.toList());
System.out.println(results);
StreamはNull保証されるので、アウトプットの配列のために、new ArrayList()しなくてよい。
Streamでかけないものもあるので無理はしない。
Q&A
Q1. 変換処理部はメソッド参照できるとおもうのですが?
A1. 書けます。しかし、読む人に優しくないので、あまり好ましくない。
Q2. 例外がうまくかけない。ベストプラクティスはあるか
A2. 正解はない。eitherを使うと良い
補足
御本人が、既に発表資料を投稿されていたので、こちらの記事は参考程度に・・・。