Перейти к содержимому

Как работает stringbuilder java

  • автор:

StringBuffer и StringBuilder

1. Отличие между String, StringBuilder, StringBuffer

  1. Классы StringBuffer и StringBuilder в Java используются, когда возникает необходимость сделать много изменений в строке символов.
  2. В отличие от String , объекты типа StringBuffer и StringBuilder могут быть изменены снова и снова.
  3. В Java StringBuilder был введен начиная с Java 5.
  4. Основное различие между StringBuffer и StringBuilder в Java является то, что методы StringBuilder не являются безопасными для потоков (несинхронизированные).
  5. Рекомендуется использовать StringBuilder всякий раз, когда это возможно, потому что он быстрее, чем StringBuffer в Java.
  6. Однако, если необходима безопасность потоков, наилучшим вариантом являются объекты StringBuffer .

2. Конструкторы StringBuilder

  • StringBuilder() — объект StringBuilder можно создать без параметров, при этом в нем будет зарезервировано место для размещения 16 символов.
  • StringBuilder(int size) — вы также можете передать конструктору целое число, для того чтобы явно задать требуемый размер буфера.
  • StringBuilder(String str) — вы можете передать конструктору строку, при этом она будет скопирована в объект и дополнительно к этому в нем будет зарезервировано место еще для 16 символов.
  • StringBuilder(CharSequence chars)

В следующем примере создадим объект класса StringBuilder , и выведем на консоль его размер методом length() . Метод capacity() возвращает размер буфера:

public class StringBuilderDemo1 < public static void main(String[] args) < StringBuilder stringBuilder = new StringBuilder("Hello"); System.out.println("string = " + stringBuilder); System.out.println("length = " + stringBuilder.length()); System.out.println("capacity header3">3. Методы charAt(), setCharAt() 

Метод charAt() возвращает символ в указанной позиции. А setCharAt() изменяет символ в указанной позиции:

public class SetCharAtDemo < public static void main(String[] args) < StringBuilder sb = new StringBuilder("Hello"); System.out.println(sb); System.out.println("charAt(1) header4">4. Метод append() 

Метод append() присоединяет подстроку к строке:

public class AppendDemo < public static void main(String[] args) < int a = 42; StringBuilder sb = new StringBuilder(40); String s = sb.append("a = ").append(a).append("!").toString(); System.out.println(s); >>

5. Метод insert()

Метод insert() вставляет подстроку в указанную позицию:

public class InsertDemo < public static void main(String[] args) < StringBuilder sb = new StringBuilder("I Java!"); sb.insert(2, "like "); System.out.println(sb); >>

6. Метод reverse()

Используется для инвертирования строки:

public class ReverseDemo < public static void main(String[] args) < StringBuilder s = new StringBuilder("abcdef"); System.out.println(s); s.reverse(); System.out.println(s); >>

7. Методы delete() и deleteCharAt()

Метод delete() удаляет подстроку, используя указанные позиции.

Метод deleteCharAt() удаляет символ с указанной позиции:

public class DeleteDemo < public static void main(String[] args) < StringBuilder sb = new StringBuilder("This is a test."); sb.delete(4, 7); System.out.println("После delete: " + sb); sb.deleteCharAt(0); System.out.println("После deleteCharAt: " + sb); >>

8. Метод replace()

Заменяет подстроку в указанной позиции другой:

public class ReplaceDemo < public static void main(String[] args) < StringBuilder stringBuilder = new StringBuilder("Этo простой тест."); stringBuilder.replace(4, 11, "был"); System.out.println("После замены: " + stringBuilder); >>

9. Методы equals() и hashCode()

Классы StringBuilder и StringBuffer не переопределяют методы equals() и hashCode() . Они используют реализацию класса Object :

public class StringBuilderEquals < public static void main(String[] args) < StringBuilder stringBuilder1 = new StringBuilder("Hello"); StringBuilder stringBuilder2 = new StringBuilder("Hello"); System.out.println(stringBuilder1.equals(stringBuilder2)); System.out.println(stringBuilder1 == stringBuilder2); >>

StringBuilder — Java: Массивы

Генерация строк в циклах — задача, часто возникающая на практике. Типичный пример — метод, помогающий генерировать HTML-списки. Он принимает на вход массив элементов и возвращает HTML-список из них:

Как можно решить эту задачу "в лоб":

  1. Создать переменную result и записать в нее
      .
    • Пройтись циклом по элементам коллекции и дописать в результирующую строку очередной элемент
    • .
    • Добавить в конце

    и вернуть result из функции.

Такой способ вполне рабочий, но для большинства языков программирования максимально неэффективный. Дело в том, что конкатенация порождает новую строчку вместо старой, — и подобная ситуация повторяется на каждой итерации. Причем строка становится все больше и больше. Копирование строк приводит к серьезному расходу памяти и влияет на производительность.

Правильный способ для динамической сборки строк в Java - использование класса StringBuilder . Он позволяет собирать строку по кусочкам без лишнего копирования. Перепишем наш пример:

Открыть доступ

Курсы программирования для новичков и опытных разработчиков. Начните обучение бесплатно

  • 130 курсов, 2000+ часов теории
  • 1000 практических заданий в браузере
  • 360 000 студентов

Наши выпускники работают в компаниях:

Как работает stringbuilder java

Объекты String являются неизменяемыми, поэтому все операции, которые изменяют строки, фактически приводят к созданию новой строки, что сказывается на производительности приложения. Для решения этой проблемы, чтобы работа со строками проходила с меньшими издержками в Java были добавлены классы StringBuffer и StringBuilder . По сути они напоминает расширяемую строку, которую можно изменять без ущерба для производительности.

Эти классы похожи, практически двойники, они имеют одинаковые конструкторы, одни и те же методы, которые одинаково используются. Единственное их различие состоит в том, что класс StringBuffer синхронизированный и потокобезопасный. То есть класс StringBuffer удобнее использовать в многопоточных приложениях, где объект данного класса может меняться в различных потоках. Если же речь о многопоточных приложениях не идет, то лучше использовать класс StringBuilder, который не потокобезопасный , но при этом работает быстрее, чем StringBuffer в однопоточных приложениях.

StringBuffer определяет четыре конструктора:

StringBuffer() StringBuffer(int capacity) StringBuffer(String str) StringBuffer(CharSequence chars)

Аналогичные конструкторы определяет StringBuilder:

StringBuilder() StringBuilder(int capacity) StringBuilder(String str) StringBuilder(CharSequence chars)

Рассмотрим работу этих классов на примере функциональности StringBuffer.

При всех операциях со строками StringBuffer / StringBuilder перераспределяет выделенную память. И чтобы избежать слишком частого перераспределения памяти, StringBuffer/StringBuilder заранее резервирует некоторую область памяти, которая может использоваться. Конструктор без параметров резервирует в памяти место для 16 символов. Если мы хотим, чтобы количество символов было иным, то мы можем применить второй конструктор, который в качестве параметра принимает количество символов.

Третий и четвертый конструкторы обоих классов принимают строку и набор символов, при этом резервируя память для дополнительных 16 символов.

С помощью метода capacity() мы можем получить количество символов, для которых зарезервирована память. А с помощью метода ensureCapacity() изменить минимальную емкость буфера символов:

String str = "Java"; StringBuffer strBuffer = new StringBuffer(str); System.out.println("Емкость: " + strBuffer.capacity()); // 20 strBuffer.ensureCapacity(32); System.out.println("Емкость: " + strBuffer.capacity()); // 42 System.out.println("Длина: " + strBuffer.length()); // 4

Так как в самом начале StringBuffer инициализируется строкой "Java", то его емкость составляет 4 + 16 = 20 символов. Затем мы увеличиваем емкость буфера с помощью вызова strBuffer.ensureCapacity(32) повышаем минимальную емкость буфера до 32 символов. Однако финальная емкость может отличаться в большую сторону. Так, в данном случае я получаю емкость не 32 и не 32 + 4 = 36, а 42 символа. Дело в том, что в целях повышения эффективности Java может дополнительно выделять память.

Но в любом случае вне зависимости от емкости длина строки, которую можно получить с помощью метода length() , в StringBuffer остается прежней - 4 символа (так как в "Java" 4 символа).

Чтобы получить строку, которая хранится в StringBuffer, мы можем использовать стандартный метод toString() :

String str = "Java"; StringBuffer strBuffer = new StringBuffer(str); System.out.println(strBuffer.toString()); // Java

По всем своим операциям StringBuffer и StringBuilder напоминают класс String.

Получение и установка символов

Метод charAt() получает, а метод setCharAt() устанавливает символ по определенному индексу:

StringBuffer strBuffer = new StringBuffer("Java"); char c = strBuffer.charAt(0); // J System.out.println(c); strBuffer.setCharAt(0, 'c'); System.out.println(strBuffer.toString()); // cava

Метод getChars() получает набор символов между определенными индексами:

StringBuffer strBuffer = new StringBuffer("world"); int startIndex = 1; int endIndex = 4; char[] buffer = new char[endIndex-startIndex]; strBuffer.getChars(startIndex, endIndex, buffer, 0); System.out.println(buffer); // orl

Добавление в строку

Метод append() добавляет подстроку в конец StringBuffer:

StringBuffer strBuffer = new StringBuffer("hello"); strBuffer.append(" world"); System.out.println(strBuffer.toString()); // hello world

Метод insert() добавляет строку или символ по определенному индексу в StringBuffer:

StringBuffer strBuffer = new StringBuffer("word"); strBuffer.insert(3, 'l'); System.out.println(strBuffer.toString()); //world strBuffer.insert(0, "s"); System.out.println(strBuffer.toString()); //sworld

Удаление символов

Метод delete() удаляет все символы с определенного индекса о определенной позиции, а метод deleteCharAt() удаляет один символ по определенному индексу:

StringBuffer strBuffer = new StringBuffer("assembler"); strBuffer.delete(0,2); System.out.println(strBuffer.toString()); //sembler strBuffer.deleteCharAt(6); System.out.println(strBuffer.toString()); //semble

Обрезка строки

Метод substring() обрезает строку с определенного индекса до конца, либо до определенного индекса:

StringBuffer strBuffer = new StringBuffer("hello java!"); String str1 = strBuffer.substring(6); // обрезка строки с 6 символа до конца System.out.println(str1); //java! String str2 = strBuffer.substring(3, 9); // обрезка строки с 3 по 9 символ System.out.println(str2); //lo jav

Изменение длины

Для изменения длины StringBuffer (не емкости буфера символов) применяется метод setLength() . Если StringBuffer увеличивается, то его строка просто дополняется в конце пустыми символами, если уменьшается - то строка по сути обрезается:

StringBuffer strBuffer = new StringBuffer("hello"); strBuffer.setLength(10); System.out.println(strBuffer.toString()); //"hello " strBuffer.setLength(4); System.out.println(strBuffer.toString()); //"hell"

Замена в строке

Для замены подстроки между определенными позициями в StringBuffer на другую подстроку применяется метод replace() :

StringBuffer strBuffer = new StringBuffer("hello world!"); strBuffer.replace(6,11,"java"); System.out.println(strBuffer.toString()); //hello java!

Первый параметр метода replace указывает, с какой позиции надо начать замену, второй параметр - до какой позиции, а третий параметр указывает на подстроку замены.

Обратный порядок в строке

Метод reverse() меняет порядок в StringBuffer на обратный:

StringBuffer strBuffer = new StringBuffer("assembler"); strBuffer.reverse(); System.out.println(strBuffer.toString()); //relbmessa

Как работает stringbuilder java

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

Строки должны всегда использоваться, если строковые разработчики не предлагают преимущества с точки зрения более простого кода (см. пример программы в конце этого раздела), или лучшая производительность. Например, если Вы должны связать большое количество строк, добавляя к a StringBuilder объект более эффективен.

Длина и Емкость

StringBuilder class, как String class, имеет a length() метод, который возвращает длину символьной последовательности в разработчике.

В отличие от строк, у каждого строкового разработчика также есть емкость, число символьных мест, которые были выделены. Емкость, которая возвращается capacity() метод, всегда больше чем или равен длине (обычно больше чем) и автоматически расширится по мере необходимости, чтобы разместить дополнения к строковому разработчику.

StringBuilder Конструкторы

Конструктор Описание
StringBuilder() Создает пустого строкового разработчика с емкостью 16 (16 пустых элементов).
StringBuilder(CharSequence cs) Создает строкового разработчика, содержащего те же самые символы как указанное CharSequence , плюс дополнительные 16 пустые элементы, запаздывающие CharSequence .
StringBuilder(int initCapacity) Создает пустого строкового разработчика с указанной начальной емкостью.
StringBuilder(String s) Создает строкового разработчика, значение которого инициализируется указанной строкой плюс дополнительные 16 пустые элементы, запаздывающие строка.

Например, следующий код

// creates empty builder, capacity 16 StringBuilder sb = new StringBuilder(); // adds 9 character string at beginning sb.append("Greetings");

произведет строкового разработчика с длиной 9 и емкостью 16:

StringBuilder У class есть некоторые методы, связанные с длиной и емкостью что String class не имеет:

Длина и Методы Емкости

Метод Описание
void setLength(int newLength) Устанавливает длину символьной последовательности. Если newLength меньше чем length() , последние знаки в символьной последовательности являются усеченными. Если newLength больше чем length() , нулевые символы добавляются в конце символьной последовательности.
void ensureCapacity(int minCapacity) Гарантирует, что емкость, по крайней мере, равна указанному минимуму.

Много операций (например, append() , insert() , или setLength() ) может увеличить длину символьной последовательности в строковом разработчике так, чтобы результант length() было бы больше чем ток capacity() . Когда это происходит, емкость автоматически увеличивается.

Операции StringBuilder

Основные операции на a StringBuilder это не доступно в String append() и insert() методы, которые перегружаются, чтобы принять данные любого типа. Каждый преобразовывает его параметр строке и затем добавляет или вставляет символы той строки к символьной последовательности в строковом разработчике. Добавлять метод всегда добавляет эти символы в конце существующей символьной последовательности, в то время как метод вставки добавляет символы в указанной точке.

Вот много методов StringBuilder class.

Различный StringBuilder Методы

Метод Описание
StringBuilder append(boolean b)
StringBuilder append(char c)
StringBuilder append(char[] str)
StringBuilder append(char[] str, int offset, int len)
StringBuilder append(double d)
StringBuilder append(float f)
StringBuilder append(int i)
StringBuilder append(long lng)
StringBuilder append(Object obj)
StringBuilder append(String s)
Добавляет параметр этому строковому разработчику. Данные преобразовываются в строку прежде, чем добавлять работа будет иметь место.
StringBuilder delete(int start, int end)
StringBuilder deleteCharAt(int index)
Первый метод удаляет подпоследовательность из запуска, чтобы закончиться 1 (включительно) в StringBuilder 's последовательность случайной работы. Второй метод удаляет символ, расположенный в index .
StringBuilder insert(int offset, boolean b)
StringBuilder insert(int offset, char c)
StringBuilder insert(int offset, char[] str)
StringBuilder insert(int index, char[] str, int offset, int len)
StringBuilder insert(int offset, double d)
StringBuilder insert(int offset, float f)
StringBuilder insert(int offset, int i)
StringBuilder insert(int offset, long lng)
StringBuilder insert(int offset, Object obj)
StringBuilder insert(int offset, String s)
Вставляет второй параметр в строкового разработчика. Первый целочисленный параметр указывает на индексирование, перед которым должны быть вставлены данные. Данные преобразовываются в строку прежде, чем работа вставки будет иметь место.
StringBuilder replace(int start, int end, String s)
void setCharAt(int index, char c)
Заменяет указанный символ (ы) в этом строковом разработчике.
StringBuilder reverse() Инвертирует последовательность символов в этом строковом разработчике.
String toString() Возвращает строку, которая содержит символьную последовательность в разработчике.

Отметьте: можно использовать любого String метод на a StringBuilder объект первым преобразованием строкового разработчика к строке с toString() метод StringBuilder class. Затем преобразуйте строку назад в строкового разработчика, использующего StringBuilder(String str) конструктор.

Пример

StringDemo программа, которая была перечислена в разделе, названном "Строки", является примером программы, которая была бы более эффективной если a StringBuilder использовались вместо a String .

StringDemo инвертированный палиндром. Здесь, еще раз, его перечисление:

public class StringDemo < public static void main(String[] args) < String palindrome = "Dot saw I was Tod"; int len = palindrome.length(); char[] tempCharArray = new char[len]; char[] charArray = new char[len]; // put original string in an // array of chars for (int i = 0; i < len; i++) < tempCharArray[i] = palindrome.charAt(i); >// reverse array of chars for (int j = 0; j < len; j++) < charArray[j] = tempCharArray[len - 1 - j]; >String reversePalindrome = new String(charArray); System.out.println(reversePalindrome); > >

Выполнение программы производит этот вывод:

doT saw I was toD

Чтобы выполнить строковое реверсирование, программа преобразовывает строку в массив символов (сначала for цикл), инвертирует массив во второй массив (второй for цикл), и затем преобразовывает назад в строку.

Если Вы преобразовываете palindrome представьте в виде строки строковому разработчику, можно использовать reverse() метод в StringBuilder class. Это делает код более простым и легче читать:

public class StringBuilderDemo < public static void main(String[] args) < String palindrome = "Dot saw I was Tod"; StringBuilder sb = new StringBuilder(palindrome); sb.reverse(); // reverse it System.out.println(sb); >>

Выполнение этой программы производит тот же самый вывод:

doT saw I was toD

Отметьте это println() печатает строкового разработчика, как в:

System.out.println(sb);

потому что sb.toString() вызывается неявно, как это с любым другим объектом в a println() вызов.

Отметьте: есть также a StringBuffer class, который является точно тем же самым как StringBuilder class, за исключением того, что это ориентировано на многопотоковое исполнение на основании синхронизации его методов. Потоки будут обсуждены в уроке на параллелизме.

Ваше использование этой страницы и всего материала на страницах под "Учебным баннером" Java подвергается этим официальным уведомлениям.

Авторское право © 1995, 2012 Oracle и/или его филиалы. Все права защищены.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *