Как переназначить значение StringBuffer?
Как мы можем повторно назначить значение переменной StringBuffer или StringBuilder?
StringBuffer sb=new StringBuffer("teststr");
теперь мне нужно изменить значение sb на" testString " без опорожнения содержимого. Я рассматриваю метод, который может выполнять это назначение напрямую без использования отдельного выделения памяти.Я думаю, что мы можем сделать это только после опорожнения содержимого.
8 ответов
прежде всего следует упомянуть, что StringBuilder
обычно предпочтительнее StringBuffer
. От StringBuffer
собственный API:
начиная с выпуска JDK 5, Этот класс был дополнен эквивалентным классом, предназначенным для использования одним потоком,
StringBuilder
. TheStringBuilder
класс обычно следует использовать в предпочтении к этому, так как он поддерживает все те же операции, но он быстрее, так как он не выполняет синхронизацию.
что сказал, я будет придерживаться StringBuffer
для остальной части ответа, потому что это то, что вы спрашиваете; все, что StringBuffer
нет, StringBuilder
также... кроме синхронизации, которая обычно не нужна. Поэтому, если вы не используете буфер в нескольких потоках, переключитесь на StringBuilder
- это простая задача.
вопрос
StringBuffer sb = new StringBuffer("teststr");
" теперь я должен изменить значение
sb
to"testString"
без опорожнения содержимого"
Итак, вы хотите sb
иметь String
стоимостью "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
содержит по крайней мере одно вхождение "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"
. А StringBuffer
нет функциональность встроенная. Вы можете попытаться сделать это самостоятельно наиболее эффективным способом, либо на месте (возможно, с 2-х проходным алгоритмом), либо с помощью второго StringBuffer
, etc.
но вместо этого я буду использовать replace(CharSequence, CharSequence)
С String
. Это будет более чем достаточно в большинстве случаев, и, безусловно, намного яснее и проще в обслуживании. Он линейный по длине входной строки, поэтому он асимптотически оптимальный.
String before = "str1str2str3";
String after = before.replace("str", "String");
assert after.equals("String1String2String3");
обсуждения
"я ищу метод, чтобы назначить значение позже, используя предыдущее расположение памяти"
точное местоположение памяти не должно быть проблемой для вас, в самом деле, как StringBuilder
и StringBuffer
перераспределит свой внутренний буфер в разные места памяти, когда это необходимо. Единственный способ предотвратить это -ensureCapacity
(или установите его через конструктор) так, чтобы его внутренний буфер всегда будет достаточно большим, и его никогда не нужно будет перераспределять.
Впрочем, даже если StringBuffer
перераспределяет свой внутренний буфер время от времени, это не должно быть проблемой в большинстве случаев. Большинство динамически растущих структур данных (ArrayList
, HashMap
и т. д.) делают их таким образом, чтобы сохранить алгоритмически оптимальные операции, воспользовавшись амортизацией затрат. Я не буду проходить амортизированный анализ здесь, но если вы не делаете системы реального времени и т. д, это не должно быть проблемой для большинства приложений.
очевидно, я не знаю особенностей вашей потребности, но есть страх преждевременной оптимизации, поскольку вы, похоже, беспокоитесь о вещах, о которых большинство людей имеют роскошь никогда не беспокоиться.
что вы имеете в виду под "переназначением"? Вы можете очистить содержимое с помощью setLength()
а затем начните добавлять новый контент, если это то, что вы имеете в виду.
редактировать: для изменения частей контента вы можете использовать replace()
.
Как правило, на этот вопрос можно легко ответить, посмотрев на документ API рассматриваемых классов.
можно использовать StringBuilder
вместо StringBuffer
, что обычно делают люди, если они могут (StringBuilder
не синхронизирован, поэтому он быстрее, но не threadsafe). Если вам нужно инициализировать содержимое одного с другим, используйте toString()
метод для получения строкового представления. Чтобы переработать существующий StringBuilder
или StringBuffer
, просто setLength(0)
.
редактировать
Вы можете перезаписать диапазон элементов с помощью
возможно, вы ищете метод replace () для StringBuffer:
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");
действительно, я думаю replace()
- Это лучший способ. Я проверил исходный код Java. Это действительно переписывает старых персонажей.
вот исходный код из 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;
}
вы можете конвертировать в/из строки следующим образом:
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
изменение всего значения StringBuffer:
StringBuffer sb = new StringBuffer("word");
sb.setLength(0); // setting its length to 0 for making the object empty
sb.append("text");
вот как вы можете изменить все значение StringBuffer.