第9章 Java 7 の機能を復習する : 問題 11 : ProcessBuilder
問題
ProcessBuilder
クラスを使って、ユーザーのホームディレクトリの全てのサブディレクトリ内の全てのファイルからクレジット番号を探すために "grep -r" を呼び出すプログラムを作成せよ。
そして、ファイル内で見つけた番号を収集せよ。
解答
クレジット番号は結構複雑な規則があるみたいだけど、単純に14~16桁の数字列とします。
正規表現で表すと
[0-9]{14,16}
となる。
// grep コマンド実行 ProcessBuilder builder = new ProcessBuilder("grep", "-r", "[0-9]{14,16}", "./"); File home = new File(System.getProperty("user.home")); builder.directory(home); File outputFile = File.createTempFile("card", ".txt"); builder.redirectOutput(Redirect.to(outputFile)); Process process = builder.start(); try { process.waitFor(); } catch (InterruptedException ex) { // 無視 } // ファイルからクレジット番号を収集 Pattern pattern = Pattern.compile("[0-9]{14,16}"); Set<String> cards = new HashSet<String>(); for (String line : Files.readAllLines(outputFile.toPath())) { Matcher matcher = pattern.matcher(line); while (matcher.find()) { cards.add(matcher.group()); } }
私のマシンは Windows なので、「ファイルからクレジット番号を収集する」方のコードは動作確認しましたが、「grep コマンド実行」がちゃんと動くかどうかは未確認です。
悪しからず。
第9章 Java 7 の機能を復習する : 問題 10 : java.util.Objects クラス その 2
問題
次のLabeledPoint
クラスのcompareTo
メソッドを実装せよ。
public class LabeledPoint { private String label; private int x; private int y; ... }
解答
Java 8 で導入されたComparator
の default メソッドthenComparing
を使えば一発なんだけど、ここは Java 7 なので我慢して…
public int compareTo(LabeledPoint other) { Objects.requireNonNull(other); if (Objects.compare(label, other.label, String.CASE_INSENSITIVE_ORDER) != 0) return Objects.compare(label, other.label, String.CASE_INSENSITIVE_ORDER); else if (Integer.compare(x, other.x) != 0) return Integer.compare(x, other.x); else return Integer.compare(y, other.y); }
第9章 Java 7 の機能を復習する : 問題 9 : java.util.Objects クラス
問題
次のLabeledPoint
クラスのequals
メソッドとhashCode
メソッドを実装せよ。
public class LabeledPoint { private String label; private int x; private int y; ... }
解答
java.util.Objects クラスを使用する。
■ equals
メソッド
public boolean equals(Object other) { if (!(other instanceof LabeledPoint)) return false; LabeledPoint point = (LabeledPoint)other; return Objects.deepEquals( new Object[]{ label, x, y}, new Object[]{point.label, point.x, point.y} ); }
■ hashCode
メソッド
public int hashCode() { return Objects.hash(label, x, y); }
第9章 Java 7 の機能を復習する : 問題 8 : Integer.compare と Integer#compareTo
問題
整数の X 座標と Y 座標をフィールドに持つPoint
クラスのcompareTo
メソッドを、Integer#compareTo
を使わないで実装せよ。
public int compareTo(Point other) { int diff = Integer.valueOf(x).compareTo(other.x); if (diff != 0) return diff; return Integer.valueOf(y).compareTo(other.y); }
解答
Integer#compareTo
メソッドは、JDK 1.2 で導入されたInteger
オブジェクト同士の比較メソッドである。
従って、毎回Integer
オブジェクトを生成することになる。
ところが Java 7 で導入されたInteger.compare
メソッドは、int
を対象としているためInteger
オブジェクトを生成する必要がない。
■ Integer.compare
メソッドを使用
public int compareTo(Point other) { int diff = Integer.compare(x, other.x); if (diff != 0) return diff; return Integer.compare(y, other.y); }
第9章 Java 7 の機能を復習する : 問題 7 : Files.copy の威力
問題
URL.openStream
とFiles.copy
を使って、Web ページの内容を読み込んで、ファイルに保存するプログラムを作成せよ。
解答
私のはてなブログをファイルに書き出してみよう。
URL url = new URL("http://closedunbounded.hatenablog.com/"); try (InputStream stream = url.openStream()) { Files.copy(stream, Paths.get("blog.html"), StandardCopyOption.REPLACE_EXISTING); }
Files.copy(InputStream, Path, CopyOption...)
メソッドは凄い便利ですね。
第9章 Java 7 の機能を復習する : 問題 5 : Files.readAllBytes の威力
問題
Files.readAllBytes
とFiles.write
を使って、ファイルから全ての文字を読み込み、逆順に書き出すプログラムを作成せよ。
解答
byte[] bytes = Files.readAllBytes(Paths.get("/usr/share/dict/words")); StringBuilder content = new StringBuilder( new String(bytes, StandardCharsets.UTF_8) ); content.reverse(); Files.write( Paths.get("/tmp/out.txt"), content.toString().getBytes(StandardCharsets.UTF_8) );
words ファイルの改行コードが CR+LF だと、LF, CR という順番で出てきますけどね。