LoginSignup
7

More than 5 years have passed since last update.

[java8] 5回目:ラムダ式とStreamAPI

Posted at

前回:ラムダ式とStreamAPI

さて、前回はStream APIを使って、

  • 対象データの集計とソート
  • 最大値の取得

のサンプルを紹介しました。引き続き、他のサンプルを見てみましょう。

StreamAPI

指定した地域、店舗名の売り上げを集計する

public class SampleSalesMain {

    /**
     * 売り上げデータ用のクラスです。
     */
    private static class Item {
        public String cityName;
        public int sale;
        public String storeName;
        public Item(String cityName, String storeName, int sale) {
            this.cityName = cityName;
            this.sale = sale;
            this.storeName = storeName;
        }
    }

    private static List<Item> items;

    /**
     * 売り上げのサンプルデータ投入用の静的コンストラクタです。
     */
    static
    {
        items = new ArrayList<>();
        for(int i = 0; i < 2000000; ++i) {
            items.add(new Item("Tokyo", "shinagawa", 150));
            items.add(new Item("Tokyo", "shinagawa", 200));
            items.add(new Item("Oosaka", "oosaka", 100));
            items.add(new Item("Tokyo", "shinagawa", 300));
            items.add(new Item("Tokyo", "shinagawa", 400));
            items.add(new Item("Oosaka", "oosaka", 100));
            items.add(new Item("Chiba", "kashiwa", 100));
        }
    }


    public static void main(String[] args) {

        // Tokyo、shinagawaの売り上げを集計する
        System.out.println("Tokyo sales is " + ramdaSampleSales("Tokyo", "shinagawa");
    }

    /**
     * ラムダ式のサンプルです。
     * 指定された地域の売り上げ集計を返します。
     */
    public static int ramdaSampleSales(String cityName, String storeName) {
        return items.stream()
            .filter(e -> e.cityName.equals(cityName))
            .filter(e -> e.storeName.equals(storeName))
            .mapToInt(e -> e.sale).sum();
    }
}

結果

Tokyo sales is 2100000000

指定した地域、店舗名の売り上げを集計する(パラレル処理)

上記の処理を、parallelStreamを使って、パラレル処理を行い、
処理時間の比較をしてみます。
売り上げデータに関しては、上記と同様のため、省略しています。

    public static void main(String[] args) {

        // Tokyo、shinagawaの売り上げを集計する
        long start = System.currentTimeMillis();
        System.out.println("Tokyo sales is " + ramdaSampleSales("Tokyo", "shinagawa"));
        long time = (System.currentTimeMillis() - start);
        System.out.println("time(s):" + time);

        // Tokyo、shinagawaの売り上げを集計する(パラレル)
        start = System.currentTimeMillis();
        System.out.println("Oosaka sales is " + ramdaSampleSales("Tokyo", "shinagawa"));
        time = (System.currentTimeMillis() - start);
        System.out.println("time(s):" + time);
    }

    /**
     * ラムダ式のサンプルです。
     * 指定された地域の売り上げ集計を返します。
     */
    public static int ramdaSampleSales(String cityName, String storeName) {
        return items.stream()
            .filter(e -> e.cityName.equals(cityName))
            .filter(e -> e.storeName.equals(storeName))
            .mapToInt(e -> e.sale).sum();
    }

    /**
     * パラレル実行のサンプルです。
     * データ量が少ない場合は、逆に遅くなるので注意が必要です。
     */
    public static int ramdaSmapleSalesPara(String cityName, String storeName) {
        return items.parallelStream()
            .filter(e -> e.cityName.equals(cityName))
            .filter(e -> e.storeName.equals(storeName))
            .mapToInt(e -> e.sale).sum();
    }

結果

Tokyo sales is 2100000000
time(msec):656
Tokyo sales is 2100000000
time(msec):512

微妙ですが、パラレル処理の方が早いです。

最後に

Stream APIの紹介はこれで終わりになります。
他にも色々ありますので、どんどん調べてみてください!

次回は、インタフェースのデフォルト実装について紹介します。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7