文字列の最初の文字を小文字にする最も効率的な方法は? 質問する

文字列の最初の文字を小文字にする最も効率的な方法は? 質問する

最初の文字を小文字にする最も効率的な方法は何ですか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 秒あたりの操作数であり、数が多いほど良いです。

テスト

  1. test1まず、Andy と Hllink のアプローチは次の通りでした。

     string = Character.toLowerCase(string.charAt(0)) + string.substring(1);
    
  2. test22番目はアンディのアプローチでした。Introspector.decapitalize()Daniel が提案しましたが、2 つのifステートメントがありませんでした。最初のifステートメントは、テストの仮定のため削除されました。2 番目のステートメントは、正確性に違反していたため (つまり、入力が"HI"を返すため"HI") 削除されました。これはほぼ最速でした。

     char c[] = string.toCharArray();
     c[0] = Character.toLowerCase(c[0]);
     string = new String(c);
    
  3. test3は の修正版ですtest2が、 の代わりにCharacter.toLowerCase()32 を追加しています。これは文字列が ASCII である場合にのみ正しく機能します。これが最も高速でした。Mikec[0] |= ' 'コメント同じパフォーマンスを発揮しました。

     char c[] = string.toCharArray();
     c[0] += 32;
     string = new String(c);
    
  4. test4使用済みStringBuilder

     StringBuilder sb = new StringBuilder(string);
     sb.setCharAt(0, Character.toLowerCase(sb.charAt(0)));
     string = sb.toString();
    
  5. test52回のsubstring()呼び出しを使用しました。

     string = string.substring(0, 1).toLowerCase() + string.substring(1);
    
  6. 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

おすすめ記事