Обзор
StringBuilder и StringBuffer - две, легко запутанные концепции. Эта статья начинается с исходного кода и просто рассматривает сходства и различия между ними.
Легко понять, что один из этих двух безопасен для потока, а защитный нить неэффективен.
Описание в Java Doc
Java Doc - это аннотация, написанная людьми, которые пишут исходный код. Давайте сначала посмотрим на Java Doc.
StringBuilder
Изменяемая последовательность символов. Этот класс обеспечивает API, совместимый с StringBuffer, но без гарантии синхронизации. Этот класс предназначен для использования в качестве замены для замены StringBuffer в местах, где строковый буфер использовался одним потоком (как обычно). Там, где это возможно, рекомендуется использовать этот класс в предпочтениях StringBuffer, поскольку он будет быстрее при большинстве реализаций.
Основными операциями на StringBuilder являются методы добавления и вставки, которые перегружены таким образом, чтобы принимать данные любого типа. Каждое эффективно преобразует данную датуму в строку, а затем добавляет или вставляет символы этой строки в строитель строк. Метод добавления всегда добавляет эти символы в конце строителя; Метод вставки добавляет символы в указанной точке.
Например, если z относится к объекту строителя строк, чье текущее содержимое является «запуск», то метод вызовет z.append («le») приведет к тому, что строитель строк будет содержать «испуг», тогда как z.insert (4, «le») изменит строитель строк, чтобы содержать «звездочку».
В целом, если SB реферий по экземпляру StringBuilder, то SB.Append (x) имеет тот же эффект, что и SB.Insert (SB.Length (), x).
Каждый строитель струн имеет емкость. Пока длина последовательности символов, содержащейся в строительном строителе, не превышает емкость, нет необходимости выделять новый внутренний буфер. Если внутренний буфер переполняется, он автоматически становится больше.
Экземпляры StringBuilder небезопасны для использования несколькими потоками. Если такая синхронизация требуется, рекомендуется использовать java.lang.stringbuffer.
Если не указано иное, передача нулевого аргумента конструктору или методу в этом классе приведет к брошению NullPointerException.
С:
1.5
Автор:
Майкл Макклоски
Смотрите также:
java.lang.stringbuffer
java.lang.string
StringBuffer
Меры, безопасная, изменяющаяся последовательность символов. Буфер строки похож на строку, но может быть изменен. В любой момент времени он содержит некоторую конкретную последовательность символов, но длина и содержание последовательности могут быть изменены с помощью определенных вызовов метода.
Строковые буферы безопасны для использования несколькими потоками. Методы синхронизируются, где это необходимо, так что все операции в каком -либо конкретном случае ведут себя так, как если бы они происходили в некотором последовательном порядке, который согласуется с порядком вызовов метода, выполненных каждым из отдельных тем.
Основными операциями на StringBuffer являются методы добавления и вставки, которые перегружены таким образом, чтобы принимать данные любого типа. Каждое эффективно преобразует данную датуму в строку, а затем добавляет или вставляет символы этой строки в буфер строки. Метод добавления всегда добавляет эти символы в конце буфера; Метод вставки добавляет символы в указанной точке.
Например, если Z относится к строковому буферу объекту, текущее содержимое которого является «запуск», то метод Call Z.Append («le») приведет к тому, что строковый буфер содержит «испуг», тогда как Z.Insert (4, «le») изменит буфер строки, чтобы содержать «звездочку».
В общем, если SB реферирует на экземпляр StringBuffer, то SB.Append (x) имеет тот же эффект, что и SB.Insert (SB.Length (),
Всякий раз, когда происходит операция, включающая исходную последовательность (например, добавление или вставка из исходной последовательности), этот класс синхронизируется только в буфере строкового буфера, выполняющего операцию, а не на источнике. Обратите внимание, что, хотя StringBuffer разработан так, чтобы быть безопасным для использования одновременно из нескольких потоков, если конструктор или операция «Приложение или вставка передается» исходной последовательности, которая обменивается по потокам, вызывающий код должен убедиться, что операция имеет последовательное и неизменное представление о последовательности источника на срок действия операции. Это может быть удовлетворена вызывающим абонент, который держит блокировку во время вызова операции, используя неизменную последовательность источника или не разделяя последовательность источников по потокам.
Каждый струнный буфер имеет емкость. Пока длина последовательности символов, содержащейся в струнном буфере, не превышает емкость, нет необходимости выделять новую внутреннюю буферную массив. Если внутренний буфер переполняется, он автоматически становится больше.
Если не указано иное, передача нулевого аргумента конструктору или методу в этом классе приведет к брошению NullPointerException.
По состоянию на выпуск JDK 5, этот класс был дополнен эквивалентным классом, предназначенным для использования одним потоком, StringBuilder. Класс StringBuilder, как правило, должен использоваться в предпочтении этому, поскольку он поддерживает все одинаковые операции, но он быстрее, поскольку он не выполняет синхронизацию.
С:
JDK1.0
Автор:
Артур Ван Хофф
Смотрите также:
java.lang.stringbuilder
java.lang.string
Javadoc Redugary
Из вышесказанного мы можем увидеть:
Как StringBuffer, так и StringBuilder можно считать переменные строки.
StringBuffer безопасен для потока и появляется первым, и он доступен в JDK1.0.
StringBuilder не является RetRead-Safe и появляется позже и существует только в JDK1.5.
Интерфейсы двух одинаковы, а StringBuilder быстрее.
На самом деле, хорошо использовать его обычно, просто знайте эти точки, но я все еще хочу увидеть, как это реализовано в исходном коде.
Исходный код
Как обеспечить безопасность нити
Вы можете увидеть из исходного кода, который наследуют абстрактный класс AbstractStringBuilder
Публичный окончательный класс StringBuffer расширяет AbstractStringBuilder, реализует Java.io.serializable, ChareSeceScencePublic Final Class StringBuilder расширяет AbstractStringBuilder реализует java.io.serializable, char -sequence
Размер кода не очень большой, строки кода StringBuilder440, строки кода StringBuffer718, а наиболее AbstractStringBuilder, в общей сложности 1440 строк кода.
С нескольких точек зрения мы смотрим на код, один - это то, на что выглядят некоторые ключевые внутренние структуры, а другой - то, как реализуются функции, которые мы обычно используем. Поскольку строка неизменна, она помещается в постоянный бассейн. Угадается, что StringBuilder и StringBuffer должны быть реализованы с использованием массива ChAR.
/*** Значение используется для хранения символов. */ char [] значение; /*** Подсчет - это количество используемых символов. */ int count;
Можно видеть, что данные хранятся со значением, а длина представлена подсчетом.
Давайте посмотрим на различные реализации нескольких общих методов.
StringBuffer
@Override public synchronized stringbuffer Append (String str) {toStringCache = null; Super.append (str); вернуть это; } / ** * @Throws stringIndexoutOfBoundSexception {@InheritDoc} * / @Override public synchronized stringbuffer insert (int offset, string str) {toStringCache = null; Super.insert (Offset, Str); вернуть это; } @Override public Synchronized String toString () {if (toStringCache == null) {toStringCache = Arrays.copyOfrange (значение, 0, count); } вернуть новую строку (toStringCache, true); }StringBuilder
@Override public StringBuilder Append (String Str) {super.append (str); вернуть это; } / ** * @Throws stringIndexoutOfBoundSexception {@InheritDoc} * / @Override publicbuilder insert (int offset, string str) {super.insert (offset, str); вернуть это; } @Override public String toString () {// Создать копию, не делитесь возвратом массива New String (значение, 0, count); }Как видно из кода, в большинстве случаев Strinbbuffer просто добавляет синхронизированное ключевое слово для обеспечения безопасности потока. Но метод ToString отличается, поэтому я расскажу об этом позже.
Инициализировать размер и как расти
Поскольку это на самом деле массив, размер и метод роста массива, начиная, очень важен. Давайте посмотрим на код.
/** * Создает струнный буфер без символов и * начальной емкостью 16 символов. */ public StringBuffer () {super (16); } /** * Создает строитель строк без символов и * начальную емкость 16 символов. */ public stringBuilder () {super (16); }Как видите, оба эти конструкторы по умолчанию указывают, что размер массива по умолчанию составляет 16.
Почему 16? Я не понял.
Что дальше, чтобы беспокоиться о том, как расти? Давайте посмотрим на реализацию добавления
public AbstractStringBuilder Append (String Str) {if (str == null) return appendnull (); int len = str.length (); EnsureCapacityInternal (Count + Len); str.getchars (0, len, значение, граф); count += len; вернуть это; } /** * Этот метод имеет тот же контракт, что и EnsureCapacity, но * никогда не синхронизируется. */ private void EnsureCapacityInternal (int MinimumCapacity) {// Код из переполнения, если (MinimumCapacity - value.length> 0) ExpandCapacity (MinimumCapacity); } /** * Это реализует семантику расширения EncureCapacity без проверки размера или синхронизации. */ void expandCapacity (int MinimumCapacity) {int newCapacity = value.length * 2 + 2; if (newcapacity - minimumcapacity <0) newcapacity = minimumcapacity; if (newcapacity <0) {if (minimumcapacity <0) // переполнить новый OutofmemoryError (); newCapacity = integer.max_value; } value = arrays.copyof (value, newcapacity); }Приведенные выше три метода объясняют, как расширить емкость.
Поместите текущую емкость *2+2
Если вновь добавленная длина больше этого значения, установите на недавно добавленное значение
Если переполнить, бросьте OutofmemoryError
Реализация ToString в StringBuffer
/*** Кэш последнего значения, возвращаемого ToString. Очищен * всякий раз, когда stringbuffer изменяется. */ private Transiet char [] toStringCache; @Override public synchronized stringbuffer Append (String str) {toStringCache = null; Super.append (str); вернуть это; } @Override public Synchronized String toString () {if (toStringCache == null) {toStringCache = Arrays.copyOfrange (значение, 0, count); } вернуть новую строку (toStringCache, true); }Как видите, определяется массив ToStringCache. Каждый раз, когда данные меняются, это устанавливается на NULL. При ToString возьмите его снова из текущих данных.
Ключевое слово Transient - предотвратить сериализованную часть этого массива.
краткое содержание
Фактически, исходный код самой Java относительно прост. Если вы можете начать с исходного кода, вы можете более глубоко понять многие принципы. В этой статье просто перечислены некоторые исходные коды и кратко объясняют сходства и различия между StringBuffer и StringBuilder. Друзья, которые заинтересованы, могут взглянуть на это сами.
Приведенная выше статья кратко рассматривает сходства и различия между StringBuilder и StringBuffer с перспективой исходного кода (всесторонний анализ) - это все контент, которым я делюсь с вами. Я надеюсь, что это может дать вам ссылку, и я надеюсь, что вы сможете поддержать Wulin.com больше.