前々からこの実装はどうなの!?と言われていた String クラスの CharSequence を引数に取る replace メソッド。
これがついに Java 9 でリファクタリングされていました!
今まであった問題
String クラスの replace (CharSequence target, CharSequence replacement) メソッドは、文字列を置換する処理です。
これが、Java 8 までのバージョンでは正規表現を使って実装していました。
public String replace(CharSequence target, CharSequence replacement) { return Pattern.compile(target.toString(), Pattern.LITERAL).matcher( this).replaceAll(Matcher.quoteReplacement(replacement.toString())); }
正規表現は様々な処理ができる反面、かなり重たい処理です。
そのため、このメソッドは大した仕様ではないにも関わらず、あまり速くありませんでした。
Java 9 の実装
Java 9 では、正規表現を使うのをやめて StringBuilder を使うように書き直されていました!
public String replace(CharSequence target, CharSequence replacement) { String tgtStr = target.toString(); String replStr = replacement.toString(); int j = indexOf(tgtStr); if (j < 0) { return this; } int tgtLen = tgtStr.length(); int tgtLen1 = Math.max(tgtLen, 1); int thisLen = length(); int newLenHint = thisLen - tgtLen + replStr.length(); if (newLenHint < 0) { throw new OutOfMemoryError(); } StringBuilder sb = new StringBuilder(newLenHint); int i = 0; do { sb.append(this, i, j).append(replStr); i = j + tgtLen; } while (j < thisLen && (j = indexOf(tgtStr, j + tgtLen1)) > 0); return sb.append(this, i, thisLen).toString(); }
indexOf で文字列を探して、StringBuilder でちょっとずつ結合していくという実装です。
Apache Commons Lang の実装とよく似ています。
たしかにこれらなら速そうです。
念のため、簡単なコードで試してみたところ、文字列の長さや検索する文字列にもよりますが、だいたい2.5倍以上速くなっていました。
特に、文字列がヒットしなかった場合は10倍以上速くなっていました。
これなら安心して使えますね!