Stream
Javaは学生以来殆ど書いたことないのですが、あの時習った時代からとても進化しており、Stream APIなんてものが追加されていました。
前回前々回と書いたmap処理みたいなことができるとのこと。
関数型プログラミングってやつみたいです。
Stream取得~中間処理~終端処理
Streamを使う時の流れは、以下のようになります。 1. 生成 2. 中間処理(filterかけたりmapしたり) 3. 終端処理(ListにしたりforEachかけたり) これだけ書いてもなんのことやら・・・コードを書いた方が分かりやすいですね。
List<Integer> data = Arrays.asList(0,1,2,3,4,5);//リストを宣言 List<Integer> stream_data = data.stream() //生成 .map(value->value*2) //中間処理 .toList(); // 終端処理 System.out.println(stream_data);//[0, 2, 4, 6, 8, 10]
生成して~map書いて~リストにする。javascriptではmapすると配列が帰ってきましたが、Streamでのmapは、Streamを返します。
そのため、StremをリストにするtoList()を最後に記載しています。
ただ、toList()で帰ってきたリストは更新ができないので、更新したい場合はこんな書き方になります。
List<Integer> data = Arrays.asList(0,1,2,3,4,5);//リストを宣言 List<Integer> stream_data = data.stream() //生成 .map(value->value*2) //中間処理 .collect(Collectors.toList()); // 終端処理 stream_data.set(1,3); System.out.println(stream_data);//[0, 3, 4, 6, 8, 10]
終端処理を変えただけ。 filterを組み合わせることもできます。
List<Integer> stream_data = data.stream() //生成 .map(value->value*2) //中間処理 .filter(value->value%3 == 0) //中間処理 .collect(Collectors.toList()); // 終端処理 System.out.println(stream_data);//[0, 6]
Streamを生成することと、終端処理が必要なこと以外はjavascriptと殆ど一緒なので、理解はしやすいですね。
今回はリストを返却しただけでしたが、終端処理にはforEach、count、max・min(InsStreamにする必要がある)等色々あります。
連番のリストを作る
javascriptで連番の配列を作るとき、こんな書き方をしたらいけるよって記事を前々回書きました。
[...Array(5).keys()]; Array(5).fill(0).map((_,index)=>index); // 0,1,2,,3,4
JavaでもStreamを使うことで可能になります。
List<Integer> lst = IntStream.range(0,5).boxed().toList(); System.out.println(lst);//[0,1,2,3,4]
IntStreamはStreamのint型。まずはこいつを生成します。
IntStreamはrangeメソッドを持っているので、値を入れて(0,1,2,3,4)を作ります。ここはjavascriptよりも分かりやすいですね。
次は見慣れないboxed()。IntStreamはtoList()やCollectors.toList()でリスト化できません。
なので、boxed()でIntStreamからStreamに変換をかけます。
最後にリスト化して終わり!
今回はリストにしただけだけど、もちろんmapと組み合わせることができます。
IntStream.rangeClosed(1,30).boxed().map(value-> { String result = ""; result = value % 3 == 0 && value % 5 == 0 ? "FizzBuzz" : value % 3 == 0 ? "Fizz" : value % 5 == 0 ? "Buzz" : value.toString(); return result; }).forEach(System.out::println);
みんな大好きFizzBuzz。rangeClosed(1,30)で指定すると、1~30が対象になります。(rangeは1~29)
mapの中で参考演算子もりもり書いてFizzBuzz。最後はメソッド参照でprintlnして終わり!