「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); } }