なみひらブログ

学んだことを日々記録する。~ since 2012/06/24 ~

「Java6以前」と「Java7&8」の言語仕様をコードで比較しました。

最近Java8の言語仕様でコードを書いていて、「このコードをJava6以前で書いたらどんな感じだっけ?」と気になったので、比較してみました。
簡潔な記載になってきて、だんだんコード量が少なくなっています。(≒バグ混入機会が減る。)~今でいう「なんで拡張for文を使っていないの?」って感じで、「なんでストリーム使ってないの?」と言われる時代も来るんですね(´Д`)

■Java7, Java8の言語仕様を使って書いた場合

/**
 * Copyright 2014 Kohsuke Namihira All Rights Reserved.
 */

package jp.co.namihira.java8;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.regex.Pattern;
import java.util.stream.Stream;

public class Main {

    /**
     * テキスト内の単語を精査し、ある文字長(以下では12文字)以上の単語を数えます。また、実行時間を計測します。
     * @param args
     */
    public static void main(String[] args) {
        // prepare
        final int MIN_LENGTH_WORD = 12;
        final String text = getTestData();
        final String REGEX = "[\\P{L}]+";

        /*** ラムダ式で登録する[Java8] ***/
        new Thread(() -> {
            // action
            /*** ストリームでカウント処理する[Java8] ※この場合ParallelStreamを使ったほうが早く処理できる。***/
            Stream<String> words = Pattern.compile(REGEX).splitAsStream(text);
            long start = System.nanoTime();
            long result = words.filter(word -> word.length() > MIN_LENGTH_WORD).count();
            long end = System.nanoTime();

            // check
            System.out.println("Stream...");
            System.out.println(" - Count : " + result);
            /*** 桁数の大きい数字をアンダーバーで区切る[Java7] ***/
            System.out.println(" - Time[sec] : " + (double)(end - start)/1_000_000_000.0);
        }).start();
    }

    private static String getTestData(){
        File testFile = getTestFile();

        StringBuilder sb = new StringBuilder();
        /*** try-with-resources文[Java7] ***/
        try (BufferedReader br = new BufferedReader(new FileReader(testFile))) {
            String str = br.readLine();
            while(str != null){
              sb.append(str);
              str = br.readLine();
            }
        /*** 例外のマルチキャッチ[Java7] ※今回は無理やりRuntimeExceptionのキャッチを入れました。本来は不要。 ***/
        } catch (IOException | RuntimeException e) {
               throw new RuntimeException(e);
        }

        return sb.toString();
    }

    private static File getTestFile() {
        final String CLASS_PATH = Thread.currentThread().getContextClassLoader()
                .getResource("").getPath();
        final String FILE_NAME = "hoge.txt";
        return new File(CLASS_PATH + "/" + FILE_NAME);
    }

}


■Java6以前の言語仕様を使って書いた場合

/**
 * Copyright 2014 Kohsuke Namihira All Rights Reserved.
 */

package jp.co.namihira.java8;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Main {

    /**
     * テキスト内の単語を精査し、ある文字長(以下では12文字)以上の単語を数えます。また、実行時間を計測します。
     * @param args
     */
    public static void main(String[] args) {
        // prepare
        final int MIN_LENGTH_WORD = 12;
        final String text = getTestData();
        final String REGEX = "[\\P{L}]+";

        /*** Runnableインタフェースの明示的に実装して登録する ***/
        new Thread(new Runnable() {

            @Override
            public void run() {
                // action
                String[] words = text.split(REGEX);

                long start = System.nanoTime();
                /*** for文/if文でカウントする ***/
                long result = 0;
                for (String word : words) {
                    if (word.length() > MIN_LENGTH_WORD) {
                        result++;
                    }
                }
                long end = System.nanoTime();

                // check
                System.out.println("for/if...");
                System.out.println(" - Count : " + result);
                /*** 桁数の大きい数字をそのまま使う(1000.0*1000.0*1000.0) ***/
                System.out.println(" - Time[sec] : " + (double)(end - start)/1000000000.0);
            }
        }).start();

    }

    private static String getTestData(){
        File testFile = getTestFile();

        StringBuilder sb = new StringBuilder();

        /*** try-catch内で操作する。 ***/
        BufferedReader br = null;
        try {
            br = new BufferedReader(new FileReader(testFile));
            String str = br.readLine();
            while(str != null){
              sb.append(str);
              str = br.readLine();
            }
        /*** 複数のcatch文(同じハンドリング処理) ※今回は無理やりRuntimeExceptionのキャッチを入れました。本来は不要。 ***/
        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (RuntimeException e) {
            throw new RuntimeException(e);
        } finally {
            /*** 必ずclose処理を書く。 ***/
            try {
                br.close();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        return sb.toString();
    }

    private static File getTestFile() {
        final String CLASS_PATH = Thread.currentThread().getContextClassLoader()
                .getResource("").getPath();
        final String FILE_NAME = "hoge.txt";
        return new File(CLASS_PATH + "/" + FILE_NAME);
    }

}