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

2018年4月14日土曜日

Java JavaSE8Gold

t f B! P L C

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登録をお願いします!
▼ブログランキング参加中!応援よろしくお願いします。

ブログ内検索

自己紹介

猫とガジェットが好きなJava屋さんです。うつ病で休職後退職し、1年半の休養後に社会復帰。・・・が、いろいろあって再び退職。さらに1年休職の後に復帰して、なんとかSE続けてます。茶トラのすずと一緒に生活していましたが、2014年9月4日に亡くなって1人に。

より詳細なプロフィールはこちら↓

↓更新情報を受け取るにはフォローをお願いします!

Instagramでフォロー

※ヘッダー及びアイコンで使用しているドロイド君は、googleが作成、提供しているコンテンツをベースに複製したものです。

▼ココナラでメンターサービスを販売しています。招待コード「C3VG3」で1000ポイントもらえます。
▼欲しい物リスト

ブログ アーカイブ

QooQ