Streamによる中間処理
Streamの中を流れる値(個々の要素)を加工/フィルターするプロセスが、中間処理です。ひとつのStream処理につき、中間処理は0個以上複数持つことが可能です。
値を加工する – mapメソッド- public <R> Stream<R> map(Function<? super T,? extends R> mapper)
- T:元の要素の型
- R:加工後の要素の型
- mapper:要素を加工するためのラムダ式
mapメソッドを利用することで、Stream内を流れる値を加工できます。加工前後のデータ型は変化しても構いません。
たとえば以下は、与えられた文字列リストから先頭文字のコードポイント値を求める例です。
StreamMap.java
\package com.example.mynavi.streamapi; import java.util.stream.Stream; public class StreamMap { public static void main(String[] args) { Stream.of("あいうえお", "かきくけこ", "さしすせそ") .map(s -> s.codePointAt(0)) .forEach(System.out::println); } }
▼
12354 12363 12373
mapメソッドによる加工前後のデータ型は変化しても構いません。この例であれば、加工前はStream<String>ですが、加工後はStream<Integer>です。
ちなみに、加工後に基本型Streamを生成したいならば、mapメソッドの代わりにmapToInt/mapToLong/mapToDoubleメソッドがあります(この例であればmapToIntメソッドを利用することでIntStreamを生成できます)。基本型Streamを利用することで、ボクシングのオーバーヘッドを軽減できます。
条件で値を絞り込む – filterメソッド- public Stream<T> filter(Predicate<? super T> predicate)
- T:要素の型
- predicate:要素を判定するラムダ式
filterメソッドは、与えられたラムダ式(predicate)がtrueを返した要素だけを残します。たとえば以下は、「あ」で始まる要素だけを残す例です。
StreamFilter.java
\package com.example.mynavi.streamapi; import java.util.stream.Stream; public class StreamFilter { public static void main(String[] args) { Stream.of("あかさか", "さくらぎちょう", "あおもり") .filter(s -> s.startsWith("あ")) .forEach(System.out::println); } }
▼
あかさか あおもり
- public Stream<T> skip(long n)
- public Stream<T> limit(long max)
- T:要素の型
- n:スキップする要素数
- max:取得する要素数
skip/limitメソッドを利用することで、Streamからn+1~n+max番目の要素を取り出せます。
StreamSkip.java
\package com.example.mynavi.streamapi; import java.util.stream.IntStream; public class StreamSkip { public static void main(String[] args) { IntStream.range(1, 10) .skip(5) .limit(3) .forEach(System.out::println); } }
▼
6 7 8
この例であれば、先頭5番目の要素をスキップして6番目の要素から3個の要素を取得する、という意味になります。
値を並べ替える – sortedメソッド- public Stream<T> sorted(Comparator<? super T> comparator)
- T:要素の型
- comparator:比較ルール
sortedメソッドを利用することで、要素をソートできます。引数comparatorを省略した場合、要素は自然順ルールで並び替えされます(文字列であれば辞書順、数値であれば大小での比較)。以下は、引数comparatorで独自の比較ルールを設定した例です。文字列長が長い順に並べ替えます。
StreamSorted.java
\package com.example.mynavi.streamapi; import java.util.stream.Stream; public class StreamSorted { public static void main(String[] args) { Stream.of("あかさか", "さくらぎちょう", "よよぎ") .sorted((s1, s2) -> s2.length() - s1.length()) .forEach(System.out::println); } }
▼
さくらぎちょう あかさか よよぎ
引数comparatorでは、引数(s1、s2)として渡された要素を比較して、
・s1 < s2であれば負数
・s1 = s2であれば0
・s1 > s2であれば正数
を返します。この例であれば、s1、s2の文字列長の差を求めることで、文字列長の大小を表しています。