16

StringBuffer または StringBuilder 変数の値を再割り当てするにはどうすればよいですか?

StringBuffer sb=new StringBuffer("teststr");

ここで、内容を空にすることなく、sb の値を「testString」に変更する必要があります。個別のメモリ割り当てを使用せずにこの割り当てを直接実行できる方法を検討しています。内容を空にした後にのみ実行できると思います。

4

8 に答える 8

28
sb.setLength(0);
sb.append("testString");
于 2010-04-07T17:35:49.120 に答える
17

StringBuilderが一般的に よりも優先されることを最初に言及しておく必要がありStringBufferます。StringBuffer独自の APIから:

リリース JDK 5 の時点で、このクラスは、単一のスレッドで使用するために設計された同等のクラスStringBuilder. このStringBuilderクラスは、同じ操作をすべてサポートしますが、同期を実行しないため高速であるため、通常はこのクラスよりも優先して使用する必要があります。

StringBufferとはいえ、それがあなたが求めていることなので、残りの答えに固執します。行うことすべてStringBufferStringBuilderまた...一般的に不要な同期を除いて。したがって、複数のスレッドでバッファを使用していない限り、切り替えStringBuilderは簡単な作業です。


質問

StringBuffer sb = new StringBuffer("teststr");

「内容を空にせずにsbtoの値を変更する必要があります」"testString"

それで、バッファsbString値を入れたいですか?"testString"これを行うには多くの方法があります。API の使用方法を説明するために、いくつかの方法をリストします。


最適な解決策: から までの最小限の編集を実行"teststr""testString"ます。これ以上速くすることは不可能です。

StringBuffer sb = new StringBuffer("teststr");
sb.setCharAt(4, 'S');
sb.append("ing");
assert sb.toString().equals("testString");

これは不必要に で上書き"tr"され"tr"ます。

StringBuffer sb = new StringBuffer("teststr");
sb.replace(4, sb.length(), "String");
assert sb.toString().equals("testString");

これには、deleteCharAtおよびによるシフトが含まれinsertます。

StringBuffer sb = new StringBuffer("teststr");
sb.deleteCharAt(4);
sb.insert(4, 'S');
sb.append("ing");
assert sb.toString().equals("testString");

"teststr"これは今では少し異なります。編集する必要があることを魔法のように認識していません"testString"StringBufferこれは、 に どこか が少なくとも 1 回出現し、"str"に置き換える必要があることのみを前提としています"String"

StringBuffer sb = new StringBuffer("strtest");
int idx = sb.indexOf("str");
sb.replace(idx, idx + 3, "String");
assert sb.toString().equals("Stringtest");

のすべてのオカレンスを"str"置き換え、それをに置き換えたいとしましょう"String"。AStringBufferにはこの機能が組み込まれていません。インプレース(おそらく2パスアルゴリズムを使用)または2番目StringBufferの .

しかし、代わりにreplace(CharSequence, CharSequence)fromを使用しStringます。ほとんどの場合、これで十分であり、間違いなくはるかに明確で保守が容易です。入力文字列の長さは線形であるため、漸近的に最適です。

String before = "str1str2str3";
String after = before.replace("str", "String");
assert after.equals("String1String2String3");

ディスカッション

「以前のメモリ位置を使用して、後で値を割り当てる方法を探しています」

正確なメモリの場所は、実際には気にする必要はありません。実際、 と の両方がStringBuilderStringBuffer必要に応じて内部バッファを別のメモリ位置に再割り当てします。これを防ぐ唯一の方法はensureCapacity、内部バッファーが常に十分な大きさになり、再割り当てする必要がないようにすることです (またはコンストラクターを介して設定します)。

ただし、StringBuffer内部バッファを時々再割り当てしても、ほとんどの場合問題にはなりません。動的に成長するほとんどのデータ構造 ( ArrayListHashMapなど) は、コストの償却を利用して、アルゴリズム的に最適な操作を維持する方法でそれらを行います。ここでは償却分析は行いませんが、リアルタイム システムなどを実行している場合を除き、ほとんどのアプリケーションで問題になることはありません。

明らかに、私はあなたのニーズの詳細を認識していませんが、ほとんどの人が心配する必要がないという贅沢を心配しているように見えるため、時期尚早の最適化の恐れがあります.

于 2010-04-12T05:29:07.373 に答える
8

「再割り当て」とはどういう意味ですか? を使用してコンテンツを空にしてsetLength()から、新しいコンテンツの追加を開始できます。

編集: コンテンツの一部を変更するには、 を使用できますreplace()

一般に、この種の質問は、問題のクラスの API ドキュメントを見ることで簡単に答えることができます。

于 2010-04-07T11:14:03.643 に答える
3

StringBuilderの代わりに aを使用できますStringBuffer。これは通常、可能な場合に人々が行うことです (StringBuilderは同期されていないため、高速ですがスレッドセーフではありません)。一方のコンテンツを他方のコンテンツで初期化する必要がある場合は、toString()メソッドを使用して文字列表現を取得します。StringBuilder既存のorをリサイクルするにはStringBuffer、単に を呼び出しますsetLength(0)

編集
関数 を使用して、要素の範囲を上書きできますreplace()。値全体を に変更するにはnewval、 を使用しますbuffer.replace(0,buffer.length(),newval)。以下も参照してください。

于 2010-04-07T11:15:10.917 に答える
2

StringBuffer の replace() メソッドを探しているかもしれません。

StringBuffer sb=new StringBuffer("teststr");
sb.replace(0, sb.length() - 1, "newstr");

内部的には、元の文字列を削除してから新しい文字列を挿入しますが、次の手順を省略できます。

StringBuffer sb=new StringBuffer("teststr");
sb.delete(0, sb.length() - 1);
sb.append("newstr");

setLength(0) を使用すると、長さゼロの StringBuffer が変数に再割り当てされますが、これはあなたが望むものではないと思います。

StringBuffer sb=new StringBuffer("teststr");
// Reassign sb to a new, empty StringBuffer
sb.setLength(0);
sb.append("newstr");
于 2010-04-07T11:41:03.913 に答える
1

replace()確かに、それが最善の方法だと思います。Java-Source コードを確認しました。それは本当に古い文字を上書きします。

replace() のソース コードは次のとおりです。

public AbstractStringBuffer replace(int start, int end, String str)
  {
    if (start < 0 || start > count || start > end)
      throw new StringIndexOutOfBoundsException(start);

    int len = str.count;
    // Calculate the difference in 'count' after the replace.
    int delta = len - (end > count ? count : end) + start;
    ensureCapacity_unsynchronized(count + delta);

    if (delta != 0 && end < count)
      VMSystem.arraycopy(value, end, value, end + delta, count - end);

    str.getChars(0, len, value, start);
    count += delta;
    return this;
  }
于 2010-04-15T12:54:06.943 に答える
0

次のように、文字列との間で変換できます。

 StringBuffer buf = new StringBuffer();
 buf.append("s1");
 buf.append("s2");

 StringBuilder sb = new StringBuilder(buf.toString());
 // Now sb, contains "s1s2" and you can further append to it
于 2010-04-07T11:15:03.723 に答える