JavaSE8 Goldへの道(Upgrade to Java SE 8 Programmer 1Z0-810 試験対策)7回目です。
一連の記事は「JavaSE8Gold」ラベルを付けていきます。
Streamを使った計算
StreamAPIの終端操作には計算を行うものがあります。
max(),min()
ストリームの要素で最大/最小のものを返します。
Optional<T> max(Comparator<? super T> comparator) Optional<T> min(Comparator<? super T> comparator)
パラメータには
Comparator
を取ります。比較の方法を教えてあげないといけないわけです。Comparator
は昔からあるインタフェースですが、元々compare
メソッドだけだったのでJava8で関数型インタフェースとして定義されています。また、defaultメソッドが多数追加されています。例えばストリームの要素から特定の値を取りだして比較する場合、
Compartor#comparing
メソッドを使います。String min = items.stream() .min(Comparator.comparing(item -> item.length())) .get();
文字列の長さで比較して最小のものを取得しています。
※最後にgetしているのは
Optional
のためで、これはまだ解説していません。もう少し後の回に解説します。Comparator
の説明は蛇足な気がしますが、もう少し書いておくと、上記例のようにプリミティブ型で比較する場合は専用のメソッドが用意されているためそちらを使った方が良いです。(オートボクシングが働いています)static <T> Comparator<T> comparingDouble(ToDoubleFunction<? super T> keyExtractor) static <T> Comparator<T> comparingLong(ToLongFunction<? super T> keyExtractor) static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor)
上記例では
comparingInt
メソッドに置き換えてもそのまま動きます。count()
ストリームの要素数を返します。それだけだとわざわざストリームをつ買う意味がないですが、
filter
メソッドで残った数を数えるときに使えます。List<String> items = Arrays.asList("abc", "ab", "abcd", "a", "abcdef"); long count = items.stream() .filter(item -> item.length() > 2) .count();
戻り値の型は
long
なので気をつけましょう。プリミティブストリーム
オートボクシングによって
Stream
クラスでもプリミティブを扱うことができますが、非効率です。
関数型インタフェースと同様に、ストリームでもプリミティブ用のクラスが用意されています。
- IntStream
- LongStream
- DoubleStream
Streamとの相互変換
各Streamには
また、
boxed
メソッドがあり、これでラッパークラスのStreamに変換することができます。逆にmapToXxx
メソッドでプリミティブストリームに変換できます。また、
mapToObj
メソッドで任意のクラスのストリームに変換することもできます。IntStream.of(1,2,3,4,5) .boxed() //IntStream→Stream<Integer>へ変換 .mapToInt(i -> Integer.valueOf(i)) //Stream<Integer>→IntStreamへ変換 .mapToObj(i -> String.valueOf(i)) //IntStream→Stream<String>へ変換 .forEach(System.out::println);
暗黙の型変換によりプリミティブストリーム間の変換を行うメソッドもあります。
- IntStream#asLongStream int→long
- IntStream#asDoubleStream int→double
- LongStream#asDoubleStream long→double
doubleからの暗黙の型変換はないので、
DoubleStream
には用意されていません。sum(),average(),summaryStatistics()
通常のストリームにはない計算メソッドが用意されています。
その名の通り要素の合計、平均、統計情報を表す
XxxSummaryStatistics
クラスを返します。XxxSummaryStatistics
はやはりプリミティブ型毎に用意されていて、合計、平均、要素数、最大、最小をいっぺんに求めることができます。range(),rangeClosed()
これはもしかしたら試験範囲外かもしれませんが、便利なので載せておきます。
IntStream
,LongStream
だけに用意されています。
1つ目の引数から2つ目の引数までの連続した数値を要素としたストリームを生成します。
range()
は2つ目の引数の値は含まず、rangeClosed()
は含みます。IntStream.rangeClosed(1, 10) .filter(i -> i % 2 == 0) .forEach(System.out::println);
実行結果
2
4
6
8
10
4
6
8
10
と、い、う、わ、け、で
今回はここまで!未だにアップグレード試験の参考書が出ていないので、今回も以下のサイトを参考にしています。あとGoldの通常試験の参考書。