2011-10-15 8 views
9

私は現時点でjavaを使用してMUD(テキストベースのゲーム)を作成しています。 MUDの主な特徴の1つは、文字列の書式設定とそれをユーザーに返すことです。これはどのようにして最高の成果を上げますかJavaを連結して文字列または書式を作成する

は、私は次の文字列を送信したいと言う:

あなたが誰かに言う「こんにちは!」 - "誰か"、 "言う"、 "こんにちは!"すべての変数です。最高のパフォーマンスが得られるでしょうか?

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

または

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

または他のいくつかのオプション?

最後に使用するのが簡単ではないことは確かですが(これはどこにでもあるため重要ですが)、+と連結することが得られているので、この時点で考えていますいくつかの大きな行と混乱している。この場合、StringBuilderを使用すると、読みにくくなってしまいます。

ここにお勧めしますか?

+7

問題が見つからず、ボトルネックになっていない限り、パフォーマンスは心配しないでください。最も読みやすくメンテナンス可能なコードにつながると思いますか? –

答えて

17

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

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は、呼び出しを行うたびに書式文字列を解析する必要があります。これは、文字列構築を最適に行うと、オーバーヘッドになりません。


私のアドバイスは、最も読みやすい方法でコードを書くことです。 プロファイリングの場合、文字列を作成する最も効率的な方法についてのみ心配しておいてください。実際のパフォーマンス上の問題です。 (現時点では、重要でないか無関係と思われるパフォーマンス上の問題に対処する方法について考えています)。フォーマット文字列を使用すると、複数の言語のサポートが簡素化される可能性があります。これは本当ですが、複数形、性別などのことに関してあなたができることには限界があります。

+1

詳細な説明をいただきありがとうございます。私はString.formatと一緒に行くつもりですが、a)aのソリューションで構築され、b)文字列をはるかに読みやすくすることで、すでに私の人生を楽にしています。 – two13

-1

String.formatがきれいに見えます。 しかし、StringBuilderを使用して、追加関数を使用して、あなたが望むストリンを作成することができます

1

プラスとのコンカチエンス、コンパイルは実行可能な方法でコードを変換できます。文字列形式ではわかりません。

私はプラスとコカテネートを好む、私はそれが下手に簡単だと思います。

0

私は正直であり、あなたがより少ないタイピングをしたい場合は最初のものを取ることをお勧めします。より多くのCスタイルの方法を探しているなら、後者を取ることをお勧めします。

私はここ1〜2分間問題になるかもしれないという考えを熟考していましたが、入力したいと思う程度になってしまったと思います。

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

+0

私の考えは、読みやすさのためです。私は "stuff" + "other stuff"と入力するのにかなり慣れていて、別のオプションを使用すると、おそらくその習慣から自分自身を破る必要があります。私が元々考えていたのは、「あなたの[動詞]から[ユーザ] [テキスト]」のようなもので、replaceall(クラス駆動型なので、setElement(動詞)動詞のような変数を追加した後、書式設定された文字列を返す)しかし、.formatを見つけて、私の元の考えがパフォーマンスにひどいと思った。 – two13

0

あなたは、ベース文字列は、多くの場合、

文字列のMyString =「あなた$ 1から$ 2 \」$ 3 \「」

それからちょうど置き換えるコピーを入手してください$ Xのようなあなたのテンプレートを保存し再利用しようとしていると仮定すると、あなたが望むものと一緒に。

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

+1

また、複数の言語をサポートすることもできます。 http://download.oracle.com/javase/tutorial/i18n/resbundle/concept.html –

-2

最高のパフォーマンスは、おそらくStringBufferを使用することです。

+1

['StringBuilder'](http://download.oracle.com/javase/1.5.0/docs/api/java/lang/StringBuilder.html)javadoc:可能であれば、このクラスを次の場所で使用することをお勧めします。ほとんどの実装ではより高速になるため、 'StringBuffer'を優先します。 --- Btw。、私は文字列の連結がそのようなアプリケーションのボトルネックであることを疑う。 – michael667

+1

同じ違い、1つは同期、1つは同期しません。同期が適切に実装されている場合、競合がなければその差はごくわずかです。(明らかに、競合がある場合、StringBuilderを使用したくないということは明らかです。) –

1

それを簡単に保つための鍵は、決してそれを見ないことです。ここに私が意味するものは次のとおりです。

Joiner join = Joiner.on(" "); 

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

私はGuava Joinerクラスを使って可読性を問題にしていません。 「参加する」よりも明白なことは何ですか?連結に関するすべての厄介なビットはうまく隠されています。 Iterableを使うことで、このメソッドをあらゆる種類のデータ構造で使用することができます。リストは最も明白です。

Guava ImmutableList(通常のリストよりも効率的です)の呼び出しの例です。リストを変更するメソッドは例外をスローするだけなので、constructMessage()がリストを変更できないという事実を正しく表しています。言葉は、ちょうど)それを消費:

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

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

String.formatは、番号と日付の書式設定が必要な場合に適しています。

関連する問題