StringBuilder и StringBuffer являются двумя часто используемыми классами для манипулирования строками. Как мы все знаем, StringBuilder является невыполнением потоком, а StringBuffer-это безопасность. Первый был добавлен JDK1.5, а последний был доступен в JDK1.0. Давайте проанализируем их внутренние реализации ниже.
1. Отношения наследования
Публичный окончательный класс StringBufferextends AbstractStringBuilderImplomements Java.io.Serializable, Char -SecureCencePublic Final Class StringBuilderExtends AbstractStringBuilderImplesments Java.io.Serializable, Charsequence
Видно, что отношения наследования между двумя классами точно одинаковы. Serializable - это сериализуемый флаг. Интерфейс Char -SecureCEND включает в себя методы Charat (), length (), sehesequence () и toString (). Класс строки также реализует этот интерфейс. Основное внимание здесь уделяется абстрактному классу AbstractStringBuilder, который инкапсулирует реализацию большинства операций StringBuilder и StringBuffer.
2. AbstractStringBuilder
1. Переменные и методы строительства
char [] value; int count; AbstractStringBuilder () {} AbstractStringBuilder (int емкость) {value = new Char [емкость];}AbstractStringBuilder использует массив CHAR [] для сохранения строк, и метод начальной емкости может быть указан во время строительства.
2. Расширить емкость
public void EnsureCapacity (int MinimumCapacity) {if (MinimumCapacity> 0) EnsureCapacityInternal (MinimumCapacity);} Private void EnsureCapacityInternal (int MinimumCapacity) {// Overflow -Consious Code, если (MinimumCapaty - значение. 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);}Метод расширения в конечном итоге реализуется с помощью ExpandCapacity (). В этом методе емкость сначала расширяется до исходной емкости плюс 2. Если она все еще меньше, чем указанная емкость в настоящее время, то новая емкость устанавливается на минимальную способность. Затем определите, переполняется ли это. Если он переполнен, установите способность на integer.max_value. Наконец, копирование значения, очевидно, является трудоемкой операцией.
3. Append () Метод
public AbstractStringBuilder Append (String Str) {if (str == null) return appendnull (); int len = str.length (); EnsureCapacityInternal (Count + Len); str.getchars (0, len, значение, граф); count += len; вернуть это; }Append () является наиболее часто используемым методом, он имеет много форм перегрузки. Вышеуказанное - один из них, который используется для добавления строк. Если STR не является нулевым, будет вызван метод appendNull (). Этот метод на самом деле добавляет такие символы, как «n», «u», «l» и «l». Если он не является нулевым, сначала разверните способность, а затем вызовите метод getChars (), чтобы добавить STR в конце значения. Наконец, сам объект возвращается, поэтому append () можно называться непрерывно.
3. StringBuilder
AbstractStringBuilder реализовал большинство необходимых методов, и необходимо вызвать только StringBuilder и StringBuffer. Давайте посмотрим на реализацию StringBuilder.
1. Конструктор
public stringBuilder () {super (16);} public StringBuilder (int емкость) {super (емкость);} public StringBuilder (String Str) {super (str.length () + 16); Append (str);} public StringBuilder (char -sequence seq) {this (seq.length () + 16); Приложение (seq);}Как видно, размер емкости по умолчанию в StringBuilder составляет 16. Конечно, вы также можете указать начальную емкость или назначить начальное значение объекту StringBuilder в существующей последовательности символов.
2. Метод Append ()
public StringBuilder Append (String str) {super.append (str); вернуть это;} public StringBuilder Append (ChareSequence S) {super.Append (s); вернуть это;}Есть много методов перегрузки для Append (), и вот два из них. Очевидно, вот метод в AbstractStringBuilder родительского класса, который называется напрямую.
3. toString ()
public String toString () {// Создать копию, не делитесь возвратом массива New String (значение, 0, count);}Метод ToString () возвращает новый строковый объект, который не обменивается памятью с исходным объектом. Фактически, то же самое относится и к методу substring () в AbstractStringBuilder.
4. Sringbuffer
Ссыновая буфера похожа на StringBuilder, но для достижения синхронизации многие методы используют LSYNCHRONIZINED MODICATION, например, следующий метод:
public Synchronized int length () {return Count;} public Synchronized StringBuffer Append (String Str) {toStringCache = null; Super.append (str); вернуть это;} public synchronized void setlength (int newlength) {toStringCache = null; Super.SetLength (newLength);} Как видите, синхронизированный действительно добавляется перед методом.
Кроме того, в методах Append () и setlength () также существует переменная ToStringCache. Эта переменная используется для последнего кеша метода ToString (). Каждый раз, когда StringBuffer изменяется, эта переменная будет назначена NULL. ToString of StringBuffer заключается в следующем:
публичная синхронизированная строка toString () {if (toStringCache == null) {toStringCache = Arrays.copyOfrange (значение, 0, count); } вернуть новую строку (toStringCache, true);}В этом методе, если ToStringCache является нулевым, он сначала кэшируется. Окончательный возвращаемый объект строки немного отличается, и этот конструктор имеет параметр true. Найдите исходный код строки и посмотрите:
String (char [] value, boolean share) {// assert share: «unsed unsed не поддерживается»; this.value = value;}Оказывается, что строковый объект, построенный этим методом конструкции, на самом деле не копирует строку, а только указывает на значение параметры конструкции, которое состоит в том, чтобы сэкономить время копирования. Тем не менее, этот конструктор имеет разрешения на доступ к пакетам и не может быть вызван в целом.
Суммировать
Выше всего об этой статье. Я надеюсь, что для всех будет полезно изучить два общепринятых класса эксплуатации в Java, StringBuilder и StringBuffer.