こんにちは。ハンドルネーム「Javaを復習する初心者」です。このサイトはプログラミング言語Javaの復習・学習をするブログです。プログラムの開発・実行はEclipseで行ってます。
スポンサーリンク
お知らせ
  • 参考文献のページ作りました。
  • Amazon.co.jpアソシエイトに参加していますが、参考文献の紹介はもしもアフィリエイトに統一しました。
  • 2016年10月9日からは投稿ペースを落とします。週1回くらいにする予定です。
スポンサーリンク

IntStreamを使ってint型配列の最大値を取得する

こんにちは。「Javaを復習する初心者」です。Java8ではIntStreamインターフェースがあります。このインターフェースのメソッドのひとつにmax()メソッドがあります。このメソッドを使って最大値を求めてみました。また、自前で最大値を求める場合との比較をしました。

int型配列の最大値を求める際にIntStream#max()メソッドを使うことができます。今回調べてみた結果、以下の2つがあります。1つ目はArraysクラスに定義されているstream()メソッドを使う方法です。2つ目はIntStreamクラスに定義されているof()メソッドを使う方法です。OptionalIntクラスが返却されます。OptionalIntクラスにはgetAsInt()メソッドが用意されています。このメソッドがint型を返却します。

プログラム

コードで書くと次のようになります。

    // 1つ目の方法
    Arrays.stream(nums).max().getAsInt()

    // 2つ目の方法
    IntStream.of(nums).max().getAsInt();

OptionalIntクラスはint値が含まれている場合も含まれていない場合もあるという状態を扱うクラスのようです。今回の実験では値は存在するため、getAsInt()が値を必ず返却します。値が含まれていない場合、getAsInt()はNoSuchElementExceptionをスローします。

自前で最大値を求めるには大抵は次のようなコードになると思います。for文とif文の組み合わせです。numsはint型配列です。

        int max = 0;
        for (int num : nums) {
            if (max < num) {
                max = num;
            }
        }

計測

上記3つの方法について、実行時間を調べてみました。1000個の要素からなるint型配列にランダムに値を格納し、上記3つの方法それぞれを30000回繰り返したときにかかった時間を計測しました。

以下、ソースと実行結果です。

import java.util.Arrays;
import java.util.Random;
import java.util.stream.IntStream;

public class HelloArraysStream {

    public static void main(String[] args) {

        Random random = new Random();
        int[] nums = new int[1000];
        for (int i = 0; i < nums.length; i++) {
            nums[i] = random.nextInt(10000);
        }

        long start, end;
        start = System.currentTimeMillis();
        for (int i = 0; i < 30000; i++) {
            test1(nums);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        for (int i = 0; i < 30000; i++) {
            test2(nums);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);

        start = System.currentTimeMillis();
        for (int i = 0; i < 30000; i++) {
            test3(nums);
        }
        end = System.currentTimeMillis();
        System.out.println(end - start);

        System.out.println("test1: " + test1(nums));
        System.out.println("test2: " + test2(nums));
        System.out.println("test3: " + test3(nums));

    }

    private static int test1(int[] nums) {
        int max = 0;
        for (int num : nums) {
            if (max < num) {
                max = num;
            }
        }
        return max;
    }

    private static int test2(int[] nums) {
        return Arrays.stream(nums).max().getAsInt();
    }

    private static int test3(int[] nums) {
        return IntStream.of(nums).max().getAsInt();
    }

}
63
438
328
test1: 9989
test2: 9989
test3: 9989

紹介順と異なりますが、test1()メソッドが自前で最大値を求めるメソッド。test2()メソッドがArraysクラスを使った場合。test3()メソッドがIntStreamクラスを使った場合です。

結果は上記の通り、自前の方法が一番速いです。