web-dev-qa-db-ja.com

Java連結して文字列またはフォーマットを作成する

現在、Javaを使用してMUD(テキストベースのゲーム)を作成しています。 MUDの主要な側面の1つは、文字列をフォーマットしてユーザーに送り返すことです。これはどのように最もよく達成されますか?

次の文字列を送信したいとします。

あなたは誰かに「こんにちは!」と言います-ここで、「誰か」、「言う」、「こんにちは!」すべて変数です。パフォーマンスに関してはどちらが最適ですか?

_"You " + verb + " to " + user + " \"" + text + "\""_

または

String.format("You %1$s to %2$s \"%3$s\"", verb, user, text)

または他のオプション?

最終的にどちらが使いやすくなるかはわかりませんが(どこにでもあるので重要です)、+と連結すると少し混乱するので、この時点で考えています。大きな線のいくつか。この場合にStringBuilderを使用すると、読みにくくなると思います。

ここに何か提案はありますか?

11
two13

文字列が単一の連結式を使用して作成されている場合。例えば.

_String s = "You " + verb + " to " + user + " \"" + text + "\"";
_

その場合、これは多かれ少なかれ、より長い風に相当します。

_StringBuilder sb = new StringBuilder();
sb.append("You");
sb.append(verb);
sb.append(" to ");
sb.append(user);
sb.append(" \"");
sb.append(text );
sb.append('"');
String s = sb.toString();
_

(実際、Javaコンパイラは前者を後者にコンパイルします...ほぼ。)

効率の問題は、中間文字列の作成、または_+=_などを使用した文字列の作成を開始するときに発生します。その時点で、StringBuilderは、作成されて破棄される中間文字列の数を減らすため、より効率的になります。

これで、String.format()を使用する場合、内部でStringBuilderを使用する必要があります。ただし、formatは、呼び出しを行うたびにフォーマットStringも解析する必要があります。これは、文字列の構築を最適に行う場合には発生しないオーバーヘッドです。


そうは言っても、私のアドバイスは、最も読みやすい方法でコードを書くことです。 profilingが、これが実際のパフォーマンスの問題であると示している場合にのみ、文字列を作成する最も効率的な方法について心配してください。 (現在、重要ではない、または無関係であることが判明する可能性のあるパフォーマンスの問題に対処する方法について考えることに時間を費やしています。)

別の回答では、フォーマット文字列を使用すると、複数の言語のサポートが簡素化される可能性があると述べています。これは事実ですが、複数形や性別などに関してできることには限界があります。

23
Stephen C

Plusと連結すると、コンパイラはコードをパフォーマンスの高い方法で変換できます。文字列形式ではわかりません。

プラスとの連結が好きです。それはアンダーサンドよりも簡単だと思います。

1

シンプルに保つための秘訣は、決して見ないことです。これが私が意味することです:

Joiner join = Joiner.on(" ");

public void constructMessage(StringBuilder sb, Iterable<String> words) {
  join.appendTo(sb, words);
}

読みやすさを問題にしないために、GuavaJoinerクラスを使用しています。 「参加」よりも明確なことは何でしょうか。連結に関する厄介な部分はすべてうまく隠されています。 Iterableを使用することで、このメソッドをあらゆる種類のデータ構造で使用できます。リストが最も明白です。

これは、Guava ImmutableListを使用した呼び出しの例です(リストを変更するメソッドは例外をスローするだけであり、constructMessage()が単語のリストを変更できないという事実を正しく表すため、通常のリストよりも効率的です。それ):

StringBuilder outputMessage = new StringBuilder();
constructMessage(outputMessage, 
         new ImmutableList.Builder<String>()
            .add("You", verb, "to", user, "\"", text, "\"")
            .build());
1
Steve J

String.formatはきれいに見えると思います。ただし、StringBuilderを使用し、追加関数を使用して、必要な文字列を作成できます。

0
Saurabh

+との連結は、String.formatを使用するよりも読みやすいと思います。

String.formatは、数値と日付をフォーマットする必要がある場合に適しています。

0
user997135

私は正直に言って、タイピングを減らしたい場合は前者を、よりCスタイルの方法を探している場合は後者を採用することをお勧めします。

私はここに1、2分座って、何が問題になるのか考えましたが、それはあなたがどれだけタイプしたいかにかかっていると思います。

他の誰かがアイデアを持っていますか?

0
nmagerko

ベース文字列を頻繁に再利用すると仮定して、次のようにテンプレートを保存します。

String mystring = "You $ 1 to $ 2 \" $ 3\""

次に、コピーを入手して、$ Xを必要なものに置き換えます。

これは、リソースファイルに対しても非常にうまく機能します。

0
Jake Thompson