Stringbuffer java что это
Классы StringBuffer и StringBuilder
Класс String представляет собой неизменяемые последовательности символов постоянной длины и частое использование объектов класса занимают много места в памяти. Класс StringBuffer представляет расширяемые и доступные для изменений последовательности символов, позволяя вставлять символы и подстроки в существующую строку и в любом месте. Данный класс гораздо экономичнее в плане потребления памяти и настоятельно рекомендуется к использованию.
Существует четыре конструктора класса:
Методы класса StringBuffer
length()
Метод позволяет получить текущую длину объекта.
capacity()
Метод позволяет получить текущий объём выделенной памяти.
Обратите внимание, что хотя слово состоит из четырёх символов, в памяти выделено запасное пространство для дополнительных 16 символов. Для такой простейшей операции выигрыша нет, но в сложных примерах, когда приходится на лету соединять множество строк, производительность резко возрастает.
ensureCapacity()
Можно предварительно выделить место для определённого количества символов, если собираетесь добавлять большое количество маленьких строк.
setLength(int length)
Устанавливает длину строки. Значение должно быть неотрицательным.
charAt(int index) и setCharAt(int index, char ch)
Можно извлечь значение отдельного символа с помощью метода charAt() и установить новое значение символа с помощью метода setCharAt(), указав индекс символа и его значение.
getChars()
Позволяет скопировать подстроку из объекта класса StringBuffer в массив. Необходимо позаботиться, чтобы массив был достаточного размера для приёма нужного количества символов указанной подстроки.
append()
Метод соединяет представление любого другого типа данных. Есть несколько перегруженных версий.
Строковое представление каждого параметра за кулисами получают через метод String.valueOf() и затем полученные строки склеиваются в итоговую строку.
insert()
Вставляет одну строку в другую. Также можно вставлять значения других типов, которые будут автоматически преобразованы в строки. Вам надо указать индекс позиции, куда будет вставляться строка.
reverse()
Позволяет изменить порядок символов на обратный.
У меня получилось практически то же самое, может метод глючит?
delete() и deleteCharAt()
Метод delete() удаляет последовательность символов, вам надо задать индекс первого символа, который надо удалить, а также индекс символа, следующего за последним из удаляемых. Метод deleteCharAt() удаляет один символ из указанной позиции.
replace()
Позволяет заменить один набор символов на другой. Нужно указать начальный и конечный индекс и строку замены.
substring()
Позволяет получить часть содержимого. Есть две формы метода. В первом случае нужно указать индекс начала позиции, с которой нужно получить подстроку. Во втором варианте указывается начальный индекс и конечный индекс, если нужно получить текст из середины строки.
Есть и другие методы
StringBuilder
Класс StringBuilder идентичен классу StringBuffer и обладает большей производительностью. Однако он не синхронизирован, поэтому его не нужно использовать в тех случаях, когда к изменяемой строке обращаются несколько потоков.
Создадим новый объект.
Добавляем новый фрагмент в существующую строку:
Соединять строки можно цепочкой.
Данный код работает чуть быстрее, чем вызов append() по отдельности. Но это будет заметно при очень больших объёмах.
14.33. Java — Классы StringBuilder и StringBuffer, и методы
Классы StringBuffer и StringBuilder в Java используются, когда возникает необходимость сделать много изменений в строке символов.
В отличие от строк, объекты типа StringBuffer и StringBuilder могут быть изменены снова и снова, оставляя после себя множество новых неиспользуемых объектов.
В Java StringBuilder был введен начиная с Java 5. Основное различие между StringBuffer и StringBuilder является то, что методы StringBuilder не являются безопасными для потоков (несинхронизированные).
Рекомендуется использовать StringBuilder всякий раз, когда это возможно, потому что он быстрее, чем StringBuffer в Java. Однако, если необходима безопасность потоков, наилучшим вариантом являются объекты StringBuffer.
Содержание
Пример
Получим следующий результат:
Методы StringBuffer
Список методов, поддерживаемых классом StringBuffer:
№ | Описание |
1 | public StringBuffer append(String s) Обновляет значение объекта, который вызывает метод. Этот метод принимает boolean, char, int, long, Strings и т.д. |
2 | public StringBuffer reverse() Этот метод изменяет значение объекта StringBuffer, который вызывает метод. |
3 | public delete(int start, int end) Удаляет строку, начиная с начального индекса до конечного индекса. |
4 | public insert(int offset, int i) Этот метод вставляет строку s в позицию упомянутую по смещению. |
5 | replace(int start, int end, String str) Этот метод заменяет символы в подстроке данного StringBuffer символами в указанной строке. |
Список других методов (за исключением методов set), которые очень похожи на методы класса строк:
StringBuffer, и как тяжело избавиться от наследия старого кода
Всем привет. Эта статья — вольный перевод поста StringBuffer, and how hard it is to get rid of legacy code. Как-то очень он мне запал в душу, поэтому решил перевести. Поехали.
Этот класс дополнен аналогичным классом предназначенным для использования в одном потоке — StringBuilder. В общем случае нужно отдавать предпочтение классу StringBuilder, так как он поддерживает все те же операции, что и этот (StringBuffer), но быстрее, так как не выполняет никаких синхронизаций.
Так, что? Получается, 10 лет спустя уже никто не использует StringBuffer!? Ну, по крайней мере, точно не для нового функционала!?
Сколько объектов создает этот код?
Как я уже писал раньше, виртуальная машина создает много объектов на старте или при загрузке основных библиотек. Гораздо больше, чем Вы могли бы представить, задавая вопрос выше:
Oracle JVM 8-й версии создает приблизительно 10_000 объектов для выполнения этой программы.
Сколько же это создается StringBuffers?
Итак, чтобы запустить JVM нужно создать много объектов, но старые классы, у которых есть более быстрая альтернатива, которой уже 10 лет не должны быть использованы, так ведь?
Пока процесс запущен, мы можем выполнить следующую команду:
129 это количество объектов StringBuffer которые создала Java 8 Update 121. Это меньше, чем в прошлый раз, когда я проверял, но всё равно, немножко удивительно.
(Проверил у себя на Java 8 update 131, получил всего 14 объектов).
А как на счет новых фич — лямбд и стримов? Они были созданы явно в последние 10 лет и используют некоторые сторонние библиотеки, вроде Objectwebs ASM. И эти разработчики точно знают внутренности виртуальной машины и должны были спроектировать новые фичи максимально легковесными.
Запускаем jmap опять и что мы видим?
Дополнительные 416 объектов для простейшей лямбды и стрима!
(Опять проверил у себя на Java 8 update 131 и получил 430 объектов, то есть разница в те же 416 объектов. Похоже, что стримы и лямбды не подчистили).
Кстати, программа выше в целом создает:
или 35_486 объектов!
Выводы
Конечно же, использование StringBuffer на старте приложения не делает особой разницы, но зная, что есть годная альтернатива и StringBuffer до сих пор используется даже в новых фичах — показывает, как трудно бывает избавится от наследия старого кода или изменить мышление людей использовать лучшие практики.
Обработка строк в Java. Часть I: String, StringBuffer, StringBuilder
Вступление
Что вы знаете о обработке строк в Java? Как много этих знаний и насколько они углублены и актуальны? Давайте попробуем вместе со мной разобрать все вопросы, связанные с этой важной, фундаментальной и часто используемой частью языка. Наш маленький гайд будет разбит на две публикации:
String
Строка — объект, что представляет последовательность символов. Для создания и манипулирования строками Java платформа предоставляет общедоступный финальный (не может иметь подклассов) класс java.lang.String. Данный класс является неизменяемым (immutable) — созданный объект класса String не может быть изменен. Можно подумать что методы имеют право изменять этот объект, но это неверно. Методы могут только создавать и возвращать новые строки, в которых хранится результат операции. Неизменяемость строк предоставляет ряд возможностей:
Создание
Мы можем создать объект класса String несколькими способами:
1. Используя строковые литералы:
Строковый литерал — последовательность символов заключенных в двойные кавычки. Важно понимать, что всегда когда вы используете строковой литерал компилятор создает объект со значением этого литерала:
2. С помощью конструкторов:
Если копия строки не требуется явно, использование этих конструкторов нежелательно и в них нет необходимости, так как строки являются неизменными. Постоянное строительство новых объектов таким способом может привести к снижению производительности. Их лучше заменить на аналогичные инициализации с помощью строковых литералов.
Конструкторы могут формировать объект строки с помощью массива символов. Происходит копирование массива, для этого используются статические методы copyOf и copyOfRange (копирование всего массива и его части (если указаны 2-й и 3-й параметр конструктора) соответственно) класса Arrays, которые в свою очередь используют платформо-зависимую реализацию System.arraycopy.
Можно также создать объект строки с помощью массива байтов. Дополнительно можно передать параметр класса Charset, что будет отвечать за кодировку. Происходит декодирование массива с помощью указанной кодировки (если не указано — используется Charset.defaultCharset(), который зависит от кодировки операционной системы) и, далее, полученный массив символов копируется в значение объекта.
Ну и наконец-то конструкторы использующие объекты StringBuffer и StringBuilder, их значения (getValue()) и длину (length()) для создания объекта строки. С этими классами мы познакомимся чуть позже.
Приведены примеры наиболее часто используемых конструкторов класса String, на самом деле их пятнадцать (два из которых помечены как deprecated).
Длина
Важной частью каждой строки есть ее длина. Узнать ее можно обратившись к объекту String с помощью метода доступа (accessor method) length(), который возвращает количество символов в строке, например:
Конкатенация
Конкатенация — операция объединения строк, что возвращает новую строку, что есть результатом объединения второй строки с окончанием первой. Операция для объекта String может быть выполнена двумя способами:
1. Метод concat
Важно понимать, что метод concat не изменяет строку, а лишь создает новую как результат слияния текущей и переданной в качестве параметра. Да, метод возвращает новый объект String, поэтому возможны такие длинные «цепочки».
2. Перегруженные операторы «+» и «+=«
Это одни с немногих перегруженных операторов в Java — язык не позволяет перегружать операции для объектов пользовательских классов. Оператор «+» не использует метод concat, тут используется следующий механизм:
Используйте метод concat, если слияние нужно провести только один раз, для остальных случаев рекомендовано использовать или оператор «+» или StringBuffer / StringBuilder. Также стоит отметить, что получить NPE (NullPointerException), если один с операндов равен null, невозможно с помощью оператора «+» или «+=«, чего не скажешь о методе concat, например:
Форматирование
Класс String предоставляет возможность создания форматированных строк. За это отвечает статический метод format, например:
Методы
Благодаря множеству методов предоставляется возможность манипулирования строкой и ее символами. Описывать их здесь нет смысла, потому что Oracle имеет хорошие статьи о манипулировании и сравнении строк. Также у вас под рукой всегда есть их документация. Хотелось отметить новый статический метод join, который появился в Java 8. Теперь мы можем удобно объединять несколько строк в одну используя разделитель (был добавлен класс java.lang.StringJoiner, что за него отвечает), например:
Это не единственное изменение класса в Java 8. Oracle сообщает о улучшении производительности в конструкторе String(byte[], *) и методе getBytes().
Преобразование
1. Число в строку
2. Строку в число
StringBuffer
Строки являются неизменными, поэтому частая их модификация приводит к созданию новых объектов, что в свою очередь расходует драгоценную память. Для решения этой проблемы был создан класс java.lang.StringBuffer, который позволяет более эффективно работать над модификацией строки. Класс является mutable, то есть изменяемым — используйте его, если Вы хотите изменять содержимое строки. StringBuffer может быть использован в многопоточных средах, так как все необходимые методы являются синхронизированными.
Создание
Существует четыре способа создания объекта класса StringBuffer. Каждый объект имеет свою вместимость (capacity), что отвечает за длину внутреннего буфера. Если длина строки, что хранится в внутреннем буфере, не превышает размер этого буфера (capacity), то нет необходимости выделять новый массив буфера. Если же буфер переполняется — он автоматически становиться больше.
Модификация
В большинстве случаев мы используем StringBuffer для многократного выполнения операций добавления (append), вставки (insert) и удаления (delete) подстрок. Тут все очень просто, например:
Все остальные методы для работы с StringBuffer можно посмотреть в документации.
StringBuilder
StringBuilder — класс, что представляет изменяемую последовательность символов. Класс был введен в Java 5 и имеет полностью идентичный API с StringBuffer. Единственное отличие — StringBuilder не синхронизирован. Это означает, что его использование в многопоточных средах есть нежелательным. Следовательно, если вы работаете с многопоточностью, Вам идеально подходит StringBuffer, иначе используйте StringBuilder, который работает намного быстрее в большинстве реализаций. Напишем небольшой тест для сравнения скорости работы этих двух классов:
Спасибо за внимание. Надеюсь статья поможет узнать что-то новое и натолкнет на удаление всех пробелов в этих вопросах. Все дополнения, уточнения и критика приветствуются.
StringBuilder
1. Изменения строк
Строки в Java — это неизменяемые объекты (immutable). Так было сделано для того, чтобы класс-строку можно было сильно оптимизировать и использовать повсеместно. Например, в качестве ключей у коллекции HashMap рекомендуется использовать только immutable-типы.
Создание объекта
Чтобы создать объект StringBuilder на основе существующей строки, нужно выполнить команду вида:
Чтобы создать пустую изменяемую строку, нужно воспользоваться командой вида:
Класс StringBuilder имеет два десятка полезных методов, вот самые важные из них:
Метод | Описание |
---|---|
Преобразовывает переданный объект в строку и добавляет к текущей строке | |
Преобразовывает переданный объект в строку и вставляет в текущую строку | |
Заменяет часть строки, заданную интервалом start..end на переданную строку | |
Удаляет из строки символ под номером index | |
Удаляет из строки символы, заданные интервалом | |
Ищет подстроку в текущей строке | |
Ищет подстроку в текущей строке с конца | |
Возвращает символ строки по его индексу | |
Возвращает подстроку, заданную интервалом | |
Разворачивает строку задом наперед. | |
Изменяет символ строки, заданный индексом на переданный | |
Возвращает длину строки в символах |
Вот краткое описание каждого метода
2. Краткое описание методов
Добавление к строке
Преобразование к стандартной строке
Код | Вывод на экран |
---|
Как удалить символ?
Код | Вывод на экран |
---|
Как заменить часть строки на другую?