- Классы StringBuffer и StringBuilder
- Методы класса StringBuffer
- length()
- capacity()
- ensureCapacity()
- setLength(int length)
- charAt(int index) и setCharAt(int index, char ch)
- getChars()
- append()
- insert()
- reverse()
- delete() и deleteCharAt()
- replace()
- substring()
- StringBuilder
- Обработка строк в Java. Часть I: String, StringBuffer, StringBuilder
- Вступление
- String
- Создание
- Длина
- Конкатенация
- Форматирование
- Методы
- Преобразование
- StringBuffer
- Создание
- Модификация
- StringBuilder
- String, StringBuilder и StringBuffer: понимаете ли вы разницу?
- String
- StringBuilder
- StringBuffer
Классы StringBuffer и StringBuilder
Класс String представляет собой неизменяемые последовательности символов постоянной длины и частое использование объектов класса занимают много места в памяти. Класс StringBuffer представляет расширяемые и доступные для изменений последовательности символов, позволяя вставлять символы и подстроки в существующую строку и в любом месте. Данный класс гораздо экономичнее в плане потребления памяти и настоятельно рекомендуется к использованию.
Существует четыре конструктора класса:
- StringBuffer() — резервирует место под 16 символов без перераспределения памяти
- StringBuffer(int capacity) — явно устанавливает размер буфера
- StringBuffer(String string) — устанавливает начальное содержимое и резервирует 16 символов без повторого резервирования
- StringBuffer(CharSequence cs) — создаёт объект, содержащий последовательность символов и резервирует место ещё под 16 символов
Методы класса 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() по отдельности. Но это будет заметно при очень больших объёмах.
Источник
Обработка строк в Java. Часть I: String, StringBuffer, StringBuilder
Вступление
Что вы знаете о обработке строк в Java? Как много этих знаний и насколько они углублены и актуальны? Давайте попробуем вместе со мной разобрать все вопросы, связанные с этой важной, фундаментальной и часто используемой частью языка. Наш маленький гайд будет разбит на две публикации:
String
Строка — объект, что представляет последовательность символов. Для создания и манипулирования строками Java платформа предоставляет общедоступный финальный (не может иметь подклассов) класс java.lang.String. Данный класс является неизменяемым (immutable) — созданный объект класса String не может быть изменен. Можно подумать что методы имеют право изменять этот объект, но это неверно. Методы могут только создавать и возвращать новые строки, в которых хранится результат операции. Неизменяемость строк предоставляет ряд возможностей:
- использование строк в многопоточных средах (String является потокобезопасным (thread-safe) )
- использование String Pool (это коллекция ссылок на String объекты, используется для оптимизации памяти)
- использование строк в качестве ключей в HashMap (ключ рекомендуется делать неизменяемым)
Создание
Мы можем создать объект класса 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, который работает намного быстрее в большинстве реализаций. Напишем небольшой тест для сравнения скорости работы этих двух классов:
Спасибо за внимание. Надеюсь статья поможет узнать что-то новое и натолкнет на удаление всех пробелов в этих вопросах. Все дополнения, уточнения и критика приветствуются.
Источник
String, StringBuilder и StringBuffer: понимаете ли вы разницу?
Все разработчики имеют дело со словами и фразами в некоторых частях кода. String — это тип данных, используемый в программировании для представления текста.
В Java есть три класса с именами String , StringBuilder и StringBuffer , где содержатся методы, написанные для операций над строками. Эти классы включены в пакет lang и импортируются в Java-код автоматически.
Здесь я расскажу подробнее об этих классах, а также о том, как и когда их использовать, чтобы облегчить себе работу со строками.
String
Строки в Java иммутабельны (не могут быть изменены). При изменении объекта String в Java каждый раз создается совершенно новый объект. В Java существует два способа объявить объект String, как это показано в примере ниже:
Разница между этими двумя способами в том, что при использовании оператора new в памяти кучи каждый раз будет создаваться новый объект String. При использовании литерала объекта, если такой объект уже существует в куче, новый объект не появится, а ссылочная переменная будет указывать на существующий объект. При использовании строкового литерала объект String в Java сохраняется в так называемом пуле строк (String Pool). Он расположен внутри памяти кучи, что помогает Java Runtime сэкономить много места, даже если для создания объекта String при этом требуется больше времени. Так что, если вы хотите каждый раз создавать новый объект String, вам следует воспользоваться оператором new, а если вы хотите сберечь память кучи, тогда используйте строковый литерал.
При использовании оператора new, если в пуле строк такого объекта не существует, то сначала он будет создан в пуле строк, а затем уже и в памяти кучи. Ссылка на созданный строковый объект в таком случае всегда указывает на объект области кучи. Но если объект String уже существует в пуле строк, то объект будет создан только в памяти кучи. Такой вопрос нередко задают на собеседованиях по Java.
Класс String также предоставляет доступ ко многим полезным методам для различных операций над строками. Вот некоторые из этих методов: substring() , charat() , length() , equals() , concat() , replace() , trim() , split() , toUpperCase() и toLowerCase() . Эти методы можно применять как по отдельности, так и в сочетании с другими методами класса String, чтобы манипулировать строками так, как нам того захочется.
Здесь значение переменной s1 не изменяется.
StringBuilder
Класс StringBuilder представляет собой альтернативу классу String, поскольку создает мутабельный (изменяемый) набор символов. Класс StringBuilder, как и класс String, содержит набор методов для управления строковыми объектами.
Классы StringBuilder и StringBuffer предоставляют важные методы, которых не предоставляет класс String, такие как insert() , delete() и reverse() . Если вы много раз совершаете какие-либо действия над строками в коде, вам следует использовать StringBuilder или StringBuffer, потому что они намного быстрее и потребляют меньше памяти, чем String. Например, если вы используете конкатенацию строк в цикле, то лучше применять StringBuilder.
Класс StringBuilder не обеспечивает синхронизацию: экземпляры класса StringBuilder не могут совместно использоваться несколькими потоками. Для операций со строками в среде, не являющейся многопоточной, стоит использовать StringBuilder, потому что он быстрее, чем StringBuffer.
StringBuffer
Как и класс StringBuilder, класс StringBuffer также создает изменяемый строковый объект. И StringBuffer содержит те же методы, что и StringBuilder. Таким образом, разница между ними в том, что класс StringBuffer — потокобезопасный и синхронизированный: экземпляры класса StringBuffer могут совместно использоваться несколькими потоками. Для операций со строками в многопоточных средах стоит использовать StringBuffer.
Здесь несколько потоков обращаются к методу hello() , поэтому для обеспечения потокобезопасности необходимо применить StringBuffer.
Надеюсь, что вы все теперь разобрались со String, StringBuilder и StringBuffer. Спасибо, что прочитали!
Источник