最初の文字を小文字にする最も効率的な方法は何ですかString
?
これを行うにはいくつかの方法が考えられます。
使用charAt()
方法substring()
String input = "SomeInputString";
String output = Character.toLowerCase(input.charAt(0)) +
(input.length() > 1 ? input.substring(1) : "");
またはchar
配列を使用して
String input = "SomeInputString";
char c[] = input.toCharArray();
c[0] = Character.toLowerCase(c[0]);
String output = new String(c);
これを実現するには他にもたくさんの素晴らしい方法があると思います。何をお勧めしますか?
ベストアンサー1
私は有望なアプローチをテストしたJMH完全なベンチマークコード。
テスト中の仮定 (毎回コーナーケースをチェックすることを避けるため): 入力文字列の長さは常に 1 より大きい。
結果
Benchmark Mode Cnt Score Error Units
MyBenchmark.test1 thrpt 20 10463220.493 ± 288805.068 ops/s
MyBenchmark.test2 thrpt 20 14730158.709 ± 530444.444 ops/s
MyBenchmark.test3 thrpt 20 16079551.751 ± 56884.357 ops/s
MyBenchmark.test4 thrpt 20 9762578.446 ± 584316.582 ops/s
MyBenchmark.test5 thrpt 20 6093216.066 ± 180062.872 ops/s
MyBenchmark.test6 thrpt 20 2104102.578 ± 18705.805 ops/s
スコアは 1 秒あたりの操作数であり、数が多いほど良いです。
テスト
test1
まず、Andy と Hllink のアプローチは次の通りでした。string = Character.toLowerCase(string.charAt(0)) + string.substring(1);
test2
2番目はアンディのアプローチでした。Introspector.decapitalize()
Daniel が提案しましたが、2 つのif
ステートメントがありませんでした。最初のif
ステートメントは、テストの仮定のため削除されました。2 番目のステートメントは、正確性に違反していたため (つまり、入力が"HI"
を返すため"HI"
) 削除されました。これはほぼ最速でした。char c[] = string.toCharArray(); c[0] = Character.toLowerCase(c[0]); string = new String(c);
test3
は の修正版ですtest2
が、 の代わりにCharacter.toLowerCase()
32 を追加しています。これは文字列が ASCII である場合にのみ正しく機能します。これが最も高速でした。Mikec[0] |= ' '
のコメント同じパフォーマンスを発揮しました。char c[] = string.toCharArray(); c[0] += 32; string = new String(c);
test4
使用済みStringBuilder
。StringBuilder sb = new StringBuilder(string); sb.setCharAt(0, Character.toLowerCase(sb.charAt(0))); string = sb.toString();
test5
2回のsubstring()
呼び出しを使用しました。string = string.substring(0, 1).toLowerCase() + string.substring(1);
test6
変化するために反射を利用するchar value[]
文字列に直接入力します。これが最も遅い方法です。try { Field field = String.class.getDeclaredField("value"); field.setAccessible(true); char[] value = (char[]) field.get(string); value[0] = Character.toLowerCase(value[0]); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); }
結論
文字列の長さが常に 0 より大きい場合は、 を使用しますtest2
。
そうでない場合は、コーナーケースを確認する必要があります。
public static String decapitalize(String string) {
if (string == null || string.length() == 0) {
return string;
}
char c[] = string.toCharArray();
c[0] = Character.toLowerCase(c[0]);
return new String(c);
}
テキストが常に ASCII であることが確実であり、このコードがボトルネックになっているために極端なパフォーマンスを求めている場合は、 を使用しますtest3
。