順を追ってイテレーションからラムダ式、ストリームAPIまでを理解
0)最初は昔の書き方
まずList型の場合、繰り返し処理は
for (int i = 0; i < string_list.size(); i++) {
String str = string_list.get(i)
System.out.println(str);
}
って書くけど、この書き方はもう古い
1)まずはイテレーション
ずばりイテレータを使ってこう書く
for(Iterator<String> i = string_list.iterator(); i.hasNext();){
String str=(String)i.next();
System.out.println(str);
}
2)ジェネリックスを使ってみる
さらにジェネリックスを使うとキャストしなくてよくなって
for(Iterator i = string_list.iterator(); i.hasNext();){
String str = i.next()
System.out.println(str);
}
となる。
3)拡張forを使ってみる
さらに拡張forを使うと
for(String str : string_list){
System.out.println(str);
}
と書けるとのこと。なるほど!少し楽!
このように、イテレータを取得して、操作して、イテレータを実行するような処理を「外部イテレータ」と言うらしい。
ここで終わりではなく、さらに覚えなくてはいけないのが...
・内部イテレータ
・ラムダ式
・Stream API
上記外部イテレータを内部イテレータに書き換えるとforEachを使って
string_list.forEach(
new Cunsumer<String>(){
public void accept(String str){
System.out.println(str);
}
}
);
となるらしい。なんか長いし難しい...
これだと並列処理とかもできたりするみたいけど、もう少しすっきりしないだろうか?
5)ラムダ式を使ってみる
上記の内部イテレータを、ラムダ式を使って書くと
string_list.forEach(
str -> {
System.out.println(str);
});
となるとのこと。なんかすっきりした!
1行だと{}を省略して
string_list.forEach(str -> System.out.println(str));
でも可!
ラムダ式の本体を省略して、メソッド参照なんかを使うと
string_list.forEach(System.out::println);
まで省略できるとか。
色々省略しすぎて逆に良く分からなくなってきた。
6)最後にStream API
上記のラムダ式をStream APIを使って書くと
string_list.stream().forEach(str -> {
System.out.println(str);
});
となるらしい。
Stream APIは中間操作と終端操作というのがあって、
string_list.stream()
.filter(str -> str.length <= 5)
.forEach(str -> System.out.println(str));
みたいに書くと5文字以下のstrだけSystem.outするみたいなこともできるっぽい!便利!
中間操作と終端操作は色々種類があるから、使いこなせれば記述もすっきりして便利だけど、馴染みのない人にはフルにラムダ式やStream APIまで使いこなしているコードは理解するのにも一苦労しそう。
最後)まとめ
単純なfor(...){}から始まり → 0)
Iteratorを使うようになり → 1)
ジェネリックスで型変換を省略するようになり → 2)
拡張forで記述を省略し → 3)
外部イテレータから内部イテレータになり → 4)
ラムダ式になり、 → 5)
最後はStream APIになる。 → 6)
順を追っていくといろいろ進化してるんだな。。。