2018年4月14日土曜日

[JavaSE8 Goldへの道] その7 ラムダ式を使用したコレクション・ストリームの操作(3)


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


と、い、う、わ、け、で

今回はここまで!

未だにアップグレード試験の参考書が出ていないので、今回も以下のサイトを参考にしています。あとGoldの通常試験の参考書。
一連の記事は「JavaSE8Gold」ラベルを付けていきます。

それではみなさまよきガジェットライフを(´∀`)ノ



▼こちらの記事もどうぞ

▼ブログを気に入っていただけたらRSS登録をお願いします!
▼ブログランキング参加中!応援よろしくお願いします。

スポンサーリンク