StringBuffer и StringBuilder

Последнее обновление: 16.09.2025

Объекты 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)

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

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

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

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

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

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

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

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

String str = "Java";
StringBuilder strBuilder = new StringBuilder(str);
System.out.println(strBuilder.toString()); // Java

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

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

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

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

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

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

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

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

StringBuilder strBuilder = new StringBuilder("hello");
strBuilder.append(" world");
System.out.println(strBuilder.toString()); // hello world

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

StringBuilder strBuilder = new StringBuilder("word");
        
strBuilder.insert(3, 'l');
System.out.println(strBuilder.toString()); //world

strBuilder.insert(0, "s");
System.out.println(strBuilder.toString()); //sworld

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

StringBuilder strBuilder = new StringBuilder("assembler");
strBuilder.reverse();
System.out.println(strBuilder.toString()); //relbmessa
Помощь сайту
Юмани:
410011174743222
Номер карты:
4048415020898850
Morty Proxy This is a proxified and sanitized view of the page, visit original site.