Главная » Java » Класс StringBuffer Java

0

Если бы класс String, который представляет объекты строк, не допускающих изменения, был единственным доступным средством, в процессе обработки строковых данных для хранения промежуточных результатов нам пришлось бы создавать новые объекты String. В качестве примера рассмотрим последовательность действий компилятора при вычислении следующего выражения:

public static String guillemete(string quote) {

return ‘«’ + quote + ‘»';

}

Если бы компилятор был ограничен возможностью использования только тех объектов, которые относятся к классу String, выполняемые им операции можно было бы описать такой схемой:

quoted = String.valueOf(‘«’).concat(quote)

.concat(string.valueOf(‘»’));

При Каждом вызове valueOf и concat создается новый объект String, так что в Процессе вычисления рассматриваемого выражения системе пришлось бы построить четыре объекта String, только один из которых пригодился бы в дальнейшем, и понести при этом неоправданно большие накладные расходы, связанные с созданием, инициализацией и утилизацией дополнительных объектов.

На самом деле, однако, компилятор действует более эффективно. В процессе вычислений промежуточных результатов он использует объект класса StringBuffer и создает объект String только в том случае, когда это действительно необходимо. Объекты StringBuffer допускают изменение содержимого, поэтому создавать новые объекты для хранения промежуточных результатов вычислений не требуется. Вычисляя выражение с помощью средств класса StringBuffer, компилятор выполняет следующие операции:

quoted= new StringBuffer().append(‘«’) appendCquote).append(‘»’).toString();

 

В процессе вычисления выражения компилятор создает единственный объект StringBuffer для хранения всей последовательности символов, инициализирует его посредством нескольких функций append, а затем с помощью метода tostring преобразует Окончательный результат в объект типа String.

Для построения и изменения строк вы вправе воспользоваться средствами Класса StringBuffer непосредственно. В его составе есть несколько конструкторов, описанных ниже.

public StringBuffer()

Создает новый объект StringBuffer со значением "" – пустую строку.

public StringBuffer(String str)

Создает новый объект StringBuffer, содержащий ту же строку, что и объект-параметр stг.

Класс StringBuffer во многом подобен Классу String он поддерживает ряд одноименных методов с теми же контрактами. Однако StringBuffer не является производным от String, поэтому обратное предположение также неверно. Эти классы совершенно независимы – они оба наследуют класс Object.

Изменение содержимого объектов StringBuffer

Существует несколько способов изменения содержимого объекта типа StringBuffer, Включая добавление символов в Конец и вставку их в середину строки. setCharAt, один из самых простых методов, позволяет заменить символ в Указанной позиции строки. Ниже рассмотрен пример метода гер1асе, который, выполняя те же функции, что и String. replace, Т.е. заменяя все Экземпляры одного заданного символа другим, оперирует объектом StringBuffer и позволяет избежать необходимости создания нового объекта строки.

public static void

replace(stringBuffer str, char oldСhar, char newСhar) {

for (int i = о; i < str.length(); i++)

 if (str.charAtCi) == oldСhar)

str.setCharAtCi, newСhar);

}

Метод setLength Класса StringBuffer выполняет усечение или удлинение строки до Указанной длины. Если при вызове setLength задается число, меньшее текущей длины строки, строка соответствующим образом Укорачивается. Если же методу передается значение, превышающее текущую длину строки, строка дополняется пустыми символами ( ‘\uOOOO’ ).

в составе класса StringBuffer определены также наборы методов append и insert, позволяющие преобразовать значение любого типа в строку, а затем присоединить результат в конец (append) либо вставить его в середину буфера (insert). Методы insert сдвигают символы строки, начиная с указанной позиции, вправо, чтобы подготовить место, достаточное для вставки новой порции данных в следующей таблице перечислены все типы, значения которых могут быть преобразованы соответствующими перегруженными вариантами методов

append и insert.

 

Существуют также такие формы методов append и insert, которые способны принимать в качестве параметра часть массива типа char. Ниже рассмотрен пример кода, который, обращаясь к различным вариантам метода append, позволяет создать объект String, содержащий строку с результатом вычисления квадратного корня целочисленного аргумента.

string sqrtlnt(int i) {

StringBuffer buf = new StringBuffer();

buf. append (" sqrt (") . append (i) . append (‘) ‘) ;

 buf.append(" = ").append(Math.sqrt(i));

return buf.toString();

}

Методы append и i nsert возвращают ссылки на текущий объект StringBuffer, что позволяет при очередном вызове метода использовать результат предыдущего вызова.

Методы insert в качестве параметров принимают два значения: первое указывает позицию в строке StringBuffer, куда следует вставить значение второго параметра после необходимого преобразования его в объект String. Вот так можно поместить в начало буфера строку, содержащую значение текущей даты:

public static StringBuffer addDate(stringBuffer buf) {

 String now = new java.util.Date().toString();

buf.insert(0, now).insert(now.length(), ": ");

return buf;

}

Метод addDate сначала создает строку, содержащую значения текущей даты и времени; с этой целью применяется стандартный класс java.util . Date, конструктор которого, используемый по умолчанию, строит объект, хранящий информацию о дате и времени своего создания. Объект типа Date преобразуется в строку, Которая вставляется в начало буфера buf; за ней вставляется литерал-разделитель. Наконец, метод возвращает ссылку на прежний, но уже дополненный буфер, который передан в качестве параметра. Таким образом, здесь мы используем тот же прием возврата ссылки на объект StringBuffer, переданной ранее в виде параметра. Этот прием, реализованный в стандартных методах класса StringBuffer, доказал свою полезность, поскольку позволяет записывать в виде единого выражения целую цепочку вызовов методов.

Метод reverse перестраивает порядок следования символов в строке StгingBuffer на обратный. Так, например, если в буфере хранилось значение "кот", после вызова reverse оно будет преобразовано в ток.

От части строки буфера нетрудно избавиться, если воспользоваться методом delete, которому следует передать значения начальной и конечной позиций символов, подлежащих удалению. Указанный сегмент строки (за исключением символа, отвечающего конечной позиции) изымается, и строка укорачивается. Чтобы удалить из строки единственный символ, можно воспользоваться методом deleteCharAt.

Существуют и более сложные формы методов замены и вставки символов.

public StringBuffer replace(int start, int end, String str) Заменяет фрагмент строки, задаваемый позициями начала (start) и конца (end, этот символ не учитывается), содержимым параметра str. Буфер удлиняется или сокращается в зависимости от того, что длиннее – строка str или заменяемый диапазон символов.

public StringBuffer insert(int pos, char[] chars, int start,

int count)

Вставляет в строку буфера, начиная с позиции pos, символы маСсива chars и сдвигает при этом символы буфера вправо, освобождая место, достаточное для вставки элементов chars. Из chars копируется count символов, начиная с элемента chars [start].

Обработка объектов StringBuffer

Чтобы получить объект String из объекта StringBuffer, достаточно вызвать метод toString последнего. Для извлечения части буфера применяются методы subString, аналогичные тем, которые имеются в составе класса String. Если необходимо представить содержимое буфера или его фрагмента в виде массива элементов типа char, можно воспользоваться методом getchars, подобным методу String .getchars.

public void getchars(int srcBegin, int srcEnd, char[] dst, int dstBegin)

Копирует символы текущей строки StringBuffer в заданный массив dst. При этом символы строки из диапазона, заданного параметрами srcBegin и srcEnd (символ на позиции srcEnd не учитывается), присваиваются элементам массива, начиная с dst [dstBegi n].

Ниже приведен пример кода, который, используя, в частности, метод getChars, удаляет фрагмент заданного буфера.

public static StringBuffer

remove(StringBuffer buf, int pos, int cnt)

{

if (pos < 0 II cnt < 0 II pos + cnt > buf.length()) throw new IndexoutOfBoundsException();

int leftover = buf.length() – (pos + cnt);

if (leftover == 0) { // простое отсечение части строки

buf.setLength(pos);

return buf;

}

char[] chrs = new char[leftover];

 buf.getchars(pos + cnt, buf.length(), chrs, 0);

 buf.setLength(pos);

buf.append(chrs);

return buf;

}

Сначала метод remove проверяет, принадлежат ли значения параметров pos и cnt допустимому диапазону. (Обработку исключения мы вправе выполнить позже, но зафиксировать факт возможной ошибки следует прямо здесь.) Затем подсчитывается количество символов строки, следующих за удаляемой частью. Если таковых  нет, часть строки просто отсекается. В противном случае эти символы извлекаются из строки с помощью метода getchars и запоминаются в массиве chrs, после чего буфер укорачивается, к нему присоединяются символы массива chrs и, наконец, искомая строка возвращается методом в виде буфера StringBuffer.

Контроль емкости буфера

Буфер объекта StringBuffer обладает определенной емкостью, равной длине строки, которая может быть размещена в объекте без дополнительных действий по выделению очередного участка памяти. Размер буфера увеличивается автоматически по мере добавления символов, но целесообразнее некоторое приемлемое значение определить и указать заранее.

Исходная емкость буфера объекта StringBuffer может быть задана посредством специального конструктора, который принимает в качестве параметра единственное значение типа int.

public StringBuffer(int capacity)

Создает объект StringBuffer заданной емкости с исходным значением, равным ""

public void ensurecapacity(int minimum)

Проверяет емкость буфера и при необходимости увеличивает ее до значения minimum.

public int capacity()

Возвращает значение текущей емкости буфера.

Используя эти методы, вы сможете избежать повинности постоянного наращивания емкости буфера. Ниже приведена новая версия метода sqrtlnt, рассмотренного в разделе 9.8.1 на странице 238, которая дает возможность задать необходимую и достаточную емкость буфера только один раз.

String sqrtlntFaster(int) {

StringBuffer buf = new StringBuffer(50);

buf.append("sqrt(") .append(i) .append(‘) ‘);

buf.append(" = ").append(Math.sqrt(i));

 return buf.tostring();

}

Единственное внесенное нами изменение состоит в использовании другой версии Конструктора, которая создает объект StгingBuffer, достаточно емкий, чтобы

вместить итоговую строку. Значение 50, вероятно, несколько превышает требуемую величину; поэтому впоследствии увеличивать буфер не придется.

Упражнение 9.4. Напишите метод для преобразования строк, содержащих десятичные числа, в такую форму, где каждые три разряда числа, начиная С младшего, отделены символом запятой. Например, если дана строка "1234567"

                                                                                                                               метод должен вернуть строку "1,234,567".       ‘

Упражнение 9.5. Дополните решение предыдущего упражнения таким образом, чтобы предусмотреть возможность передачи методу аргументов, задающих символ-разделитель и максимальное количество цифр в группе.

Источник: Арнолд, Кен, Гослинг, Джеймс, Холмс, Дэвид. Язык программирования Java. 3-е изд .. : Пер. с англ. – М. : Издательский дом «Вильяме», 2001. – 624 с. : ил. – Парал. тит. англ.

По теме:

  • Комментарии