29

基本的な文字列連結操作には何を使用する必要がありますか?

String randomString = "hello " + userName + " how are you" ?

また

String randomString = String.format("hello %s how are you ?",userName);

String.format()出力文字列のより良いアイデアが得られると思います。しかし、実際にいずれかを使用する場合の長所と短所は何ですか?

文字列リテラル プールのパフォーマンスまたは孤立したエントリに関して何かありますか。

編集:1つだけではなく、文字列内の複数のパラメーターについて話しています。5+前後。

おまけの質問: どちらを実際に使用するべきかについて、あなたの見解も教えてください。これらのいずれかまたは 3 番目の 1 つ... !! ?

4

9 に答える 9

28

あなたがパフォーマンスだけを探しているなら、私は使用StringBuilder/StringBufferすることが文字列を構築するための最も効率的な方法であると信じています。StringBuilderJavaコンパイラが、ほとんどの文字列連結を同等のものに変換するのに十分賢い場合でも。

読みやすさを求めているならString.format、それは私が思うにはるかに明確であり、私が高性能に頼る必要がない限り、これも私が使用するものです。

したがって、主な関心事がパフォーマンスではない場合、つまり、このコードが頻繁に呼び出されるパスにない場合String.formatは、結果の文字列をよりよく理解できるため、使用することをお勧めします(あなたが言ったように)。

さらに、を使用するとフォーマットを使用String.formatできます。つまり、文字列のパディング、数値、日付などのフォーマットに使用できるため、単純な連結を使用するとコードがさらに悪化します。

Chuuの編集

JADを使用すると、次のコードを確認できます。

public class Test {
    public static void main(String[] args) {
        String str = "a" + "b" + "c";
        String str2 = "foo" + str + "bar" + str;
        System.out.println(str2);
    }
}

逆コンパイルすると、次のようになります。

public class Test {
    public static void main(String[] args) {
        String str = "abc";
        String str2 = new StringBuilder("foo").append(str).append("bar").append(str).toString();
        System.out.println(str2);
    }
}

その証拠は、ファイル javapの下にJavaバイトコードを表示するユーティリティを使用して見つけることもできます。.class

public static void main(java.lang.String[] args);
    0  ldc <String "abc"> [16]
    2  astore_1 [str]
    3  new java.lang.StringBuilder [18]
    6  dup
    7  ldc <String "foo"> [20]
    9  invokespecial java.lang.StringBuilder(java.lang.String) [22]
   12  aload_1 [str]
   13  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   16  ldc <String "bar"> [29]
   18  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   21  aload_1 [str]
   22  invokevirtual java.lang.StringBuilder.append(java.lang.String) : java.lang.StringBuilder [25]
   25  invokevirtual java.lang.StringBuilder.toString() : java.lang.String [31]
   28  astore_2 [str2]
   29  getstatic java.lang.System.out : java.io.PrintStream [35]
   32  aload_2 [str2]
   33  invokevirtual java.io.PrintStream.println(java.lang.String) : void [41]
   36  return
于 2012-12-11T07:24:05.833 に答える
8

基本的な文字列連結操作には何を使用する必要がありますか?

提供する例は、さまざまな目的に役立ちます。+concatにオーバーロードされますStringString.format、名前が指定するように文字列をフォーマットするために使用されます。

文字列を連結することは、それが主な仕事ではありません。

したがって、要件が単にuse+またはconcatメソッドを連結することである場合。

これらのリンクは便利です:

パフォーマンスが重要な場合は、JavaのString.format()を使用する必要がありますか?

Javaの文字列連結よりもString.formatを使用する方が良い方法ですか?

于 2012-12-11T07:21:25.793 に答える
4

これを試して

    long t0 = System.currentTimeMillis();
        String userName = "test";
        for (int i = 0; i < 1000000; i++) {
            String randomString = "hello " + userName + " how are you?";
//          String randomString = String.format("hello %s how are you ?",userName);
        }
        System.out.println(System.currentTimeMillis() - t0);

連結が String.format の 10 倍高速であることを知って驚くでしょう。しかし、format は、数値や日付などで非常に便利なことをたくさん行うことができます。詳細については、String.format で実際に使用される java.util.Formatter API を参照してください。

于 2012-12-11T07:31:19.750 に答える
2

私の 2 セント: 常に使用String.format()

この状況では、国際化はスタイルやパフォーマンスよりもはるかに大きな懸念事項です。そのため、私は常に使用しますString.format()

英語のテキスト:"Hello " + userName + " how are you?"

ジェダイへの翻訳:userName + "you are how? Hello!"

文字列が連結されている場合、語順を変更することは、翻訳者にとって不可能ではないにしても困難になる可能性があります。この問題は、文字列のピースが増え、プレースホルダーが増えるにつれて、ますます悪化します。

于 2012-12-11T08:26:47.327 に答える
1

String.Format は次の利点があるため、より効率的だと思います。

  1. 読みやすさの向上
  2. 翻訳しやすい
  3. フォーマット プロバイダーと単純なフォーマット インジケーター (固定幅など) をフォーマット文字列で直接使用できます。
  4. 構成ファイルにフォーマット文字列を入れることで、いくつかの強力なことができます。
  5. String.Format() は、舞台裏で StringBuilder と効率的なステート マシンを使用するため、多くの場合高速ですが、.Net での文字列連結は比較的低速です。これは、文字列のサイズと置換される値の数が増加するにつれて特に当てはまります。

ありがとう。

于 2012-12-11T07:45:02.127 に答える
1

StringBuffer の使用を推奨するほとんどの人は過去に生きています。現在のベスト プラクティスは、StringBuilder を使用することです。しかし、これは変更される可能性があるので、コンパイラに任せてみませんか? 「+」のみを使用すると、コンパイラは現在の最適な実装を選択し、静的文字列を結合することもできます (「foo」 + 「bar」は単一の「foobar」になります)。

StringBuilder を明示的に割り当てる唯一の場所は、ループ内です (ループの前に作成され、ループ内で使用されます)。

何が起こるかわからない場合は、生成されたバイトコードを確認してください。

では、いつフォーマットを使用するのでしょうか? 実際のフォーマットが複雑な場合は、フォーマットを使用します。しかし、あなたは今、単純な連結について話している.

于 2012-12-11T07:30:03.677 に答える
1

個人的には、見栄えが良く、パフォーマンスに大きな影響を与えるとは思えないため、フォーマットを使用することを好みます。

于 2012-12-11T07:23:57.910 に答える
0

私の主な懸念String.formatは、これはロケール固有の操作であり、コードが別のロケールで実行されると予期しない結果になる可能性があることです。

そのコンパクトな構文は本当に素晴らしいので、ロケール以外の代替手段が欲しいです。

于 2013-09-05T14:07:55.787 に答える