Перейти к контенту

StringBuilder в Java

Программы Java используют класс StringBuilder для добавления строк. Добавление строк становится все более сложным процессом по мере того, как строки становятся длиннее.
Требуется все больше и больше памяти. Программы тормозят.

Решение. Класс StringBuilder в Java — решение этой проблемы, он просто повторно использует единственный буфер. Ускоряет добавления, вставки.

 

Пример далее импортирует java.lang.StringBuilder. Мы создаем StringBuilder. Зацикливаем и добавляем к нему пять строк и конвертируем данные в объект String. Затем отображаем полученную строку в консоли с помощью метода System.out.println.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	// Create a new StringBuilder.
	StringBuilder builder = new StringBuilder();

	// Loop and append values.
	for (int i = 0; i < 5; i++) {
	    builder.append("abc ");
	}
	// Convert to string.
	String result = builder.toString();

	// Print result.
	System.out.println(result);
    }
}

Output

abc abc abc abc abc

Часто мы используем StringBuilders в циклах. Здесь у нас часто неизвестное количество итераций. А StringBuilder оптимизирует случаи, когда происходит много вызовов append().

Следовательно использование StringBuilder в цикле может предотвратить возникновение проблемы с производительностью генерации.

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

В этом примере мы вызываем append() для результата предыдущего вызова append() и он возвращает исходный StringBuilder.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	int value1 = 300;
	double value2 = 3.14;
	short value3 = 5;
	char value4 = 'A';

	// Create StringBuilder and add four values to it.
	StringBuilder builder = new StringBuilder();
	builder.append(value1).append("\n");
	builder.append(value2).append("\n");
	builder.append(value3).append("\n");
	builder.append(value4);

	// Display results.
	String result = builder.toString();
	System.out.println(result);
    }
}

Output

300
3.14
5
A

StringBuilder имеет изменяемый буфер. Таким образом, мы можем быстро добавлять или вставлять данные. Он получает два аргумента: индекс и значение, которое мы хотим вставить.

Индекс: это первый аргумент. Чтобы вставить после второго символа, используйте значение 2. А для вставки в начале используйте ноль.

Строка: мы передаем строку (или другое значение) в качестве второго аргумента. Это данные, которые помещаются в стрингбилдер.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	// Initialize StringBuilder with this value.
	StringBuilder builder = new StringBuilder("abc");

	// Insert this substring at position 2.
	builder.insert(2, "xyz");
	System.out.println(builder);
    }
}

Output

abxyzc

Мы используем метод indexOf для поиска подстроки в данных. Если подстрока найдена, первый индекс, в котором она встречается, возвращается как int.

Не найдено: если подходящая подстрока не найдена, возвращается отрицательное значение. Мы должны часто проверять -1 при использовании indexOf.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	StringBuilder builder = new StringBuilder("abc");

	// Try to find this substring.
	int result = builder.indexOf("bc");
	System.out.println(result);

	// This substring does not exist.
	int result2 = builder.indexOf("de");
	System.out.println(result2);
    }
}

Output

1
-1

Удаление. Мы передаем ему два аргумента типа int. Первый аргумент - это начальный индекс, с которого должно начинаться удаление. И второй аргумент - это конечный индекс.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	StringBuilder builder = new StringBuilder("carrot");

	// Delete characters from index 2 to index 5.
	builder.delete(2, 5);
	System.out.println(builder);
    }
}

Output

cat

Замена. Этот метод принимает два индекса и заменяет символы в этом диапазоне указанной строкой. Replace в StringBuilder работает иначе, чем replace() в Strings.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	// Create new StringBuilder.
	StringBuilder b = new StringBuilder("abc");

	// Replace second character with "xyz".
	b.replace(1, 2, "xyz");
	System.out.println(b);
    }
}

Output

axyzc

Объединение. Мы можем добавить один StringBuilder к другому. Мы просто вызываем append() и передаем второй StringBuilder в качестве аргумента.

public class Program {
    public static void main(String[] args) {

	StringBuilder builder = new StringBuilder("cat");
	StringBuilder builder2 = new StringBuilder("dog");

	// Combine two StringBuilders.
	builder.append(builder2);

	System.out.println(builder);
    }
}

Output

catdog

Подстрока или Substring в Java. Этот метод находится в классе AbstractStringBuilder. Он предоставляет полезную возможность извлекать диапазон символов в новую строку.

Аргументы: первый аргумент - это начальный индекс желаемой подстроки. Второй аргумент - это последний индекс (а не количество символов).

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	StringBuilder builder = new StringBuilder();
	builder.append("Forest");

	// Get substring after the first two characters.
	String omitFirstTwo = builder.substring(2);
	System.out.println(omitFirstTwo);

	// Get only the first two characters in a substring.
	String firstTwo = builder.substring(0, 2);
	System.out.println(firstTwo);
    }
}

Output

rest
Fo

Перебор символов. Цикл for может перебирать символы. Мы обращаемся к методу length(), чтобы получить размер StringBuilder, а затем используем charAt() для доступа к символам.

Длина: этот метод возвращает количество символов в StringBuilder. Самый высокий индекс - это количество символов минус один.

CharAt: обращается к символу в StringBuilder. Мы можем использовать его где угодно, а не только в цикле for.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	StringBuilder builder = new StringBuilder("magic");
	// Loop over the characters in this StringBuilder.
	for (int i = 0; i < builder.length(); i++) {
	    System.out.println(builder.charAt(i));
	}
    }
}

Output

m
a
g
i
c

SetLength. Мы можем изменить длину StringBuilder с помощью setLength. Это часто бывает полезно, когда мы хотим сократить или уменьшить количество символов в объекте.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	StringBuilder builder = new StringBuilder("carrot");
	// Use setLength to remove characters from the end.
	builder.setLength(3);
	System.out.println(builder);
    }
}

Output

car

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

 

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	// Use a 100-char capacity.
	StringBuilder temp = new StringBuilder(100);
	// Add 100 characters to the StringBuilder.
	// ... Theoretically this is faster.
	for (int i = 0; i < 25; i++) {
	    temp.append("1234");
	}
	System.out.println(temp.length());
    }
}

Output

100

Reverse. В этом примере выполняется обратное преобразование. Он вызывает метод reverse(). Обратить строку легко - сначала мы должны поместить ее содержимое в StringBuilder.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	// A StringBuilder can be reversed.
	StringBuilder builder = new StringBuilder();
	builder.append("abc");
	builder.reverse();
	System.out.println(builder);
    }
}

Output

cba

StringBuilder намного быстрее делает добавление, чем String. Для добавления String требуется значительное время(251 мс), а для добавления StringBuilder требуется менее 1 мс.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	long t1 = System.currentTimeMillis();

	// Version 1: add to string.
	String value = "";
	for (int i = 0; i < 10000; i++) {
	    value += Integer.toString(i) + ' ';
	}

	long t2 = System.currentTimeMillis();

	// Version 2: append to StringBuilder.
	StringBuilder builder = new StringBuilder();
	for (int i = 0; i < 10000; i++) {
	    builder.append(i).append(' ');
	}

	long t3 = System.currentTimeMillis();

	// ... Lengths are equal.
	System.out.println(value.length());
	System.out.println(builder.length());

	// ... Times.
	System.out.println(t2 - t1);
	System.out.println(t3 - t2);
    }
}

Results

48890
48890
251 ms, String + operator    (20000 adds)
  0 ms, StringBuilder append (20000 calls)

Производительность емкости. Здесь мы возвращаемся к емкости. В этом тесте размер первого StringBuilder увеличивается до миллиона символов без установленной емкости.

И еще: второй StringBuilder тем временем использует точную емкость 1000000.

Результат: точная емкость позволяет второму StringBuilder почти в два раза быстрее выполнять свою задачу.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	long t1 = System.currentTimeMillis();

	// Version 1: does not use capacity.
	StringBuilder builder = new StringBuilder();
	for (int i = 0; i < 1000000; i++) {
	    builder.append(' ');
	}

	long t2 = System.currentTimeMillis();

	// Version 2: uses exact capacity.
	StringBuilder builder2 = new StringBuilder(1000000);
	for (int i = 0; i < 1000000; i++) {
	    builder2.append(' ');
	}

	long t3 = System.currentTimeMillis();

	// ... Times.
	System.out.println(t2 - t1);
	System.out.println(t3 - t2);
    }
}

Results

10 ms, no capacity
 6 ms, exact capacity

Добавление строки вместо символа. Вот еще один тест. Он сравнивает вызов append() с односимвольным строковым литералом и char. Аргумент String работает медленнее.

Когда это возможно: быстрее использовать аргумент char для append(), чем аргумент String. Я обнаружил, что это помогает многим программам.

import java.lang.StringBuilder;

public class Program {
    public static void main(String[] args) {

	long t1 = System.currentTimeMillis();

	// Version 1: appends one-char strings.
	StringBuilder builder = new StringBuilder();
	for (int i = 0; i < 1000000; i++) {
	    builder.append("X");
	}

	long t2 = System.currentTimeMillis();

	// Version 2: appends chars directly.
	StringBuilder builder2 = new StringBuilder();
	for (int i = 0; i < 1000000; i++) {
	    builder2.append('X');
	}

	long t3 = System.currentTimeMillis();

	// ... Times.
	System.out.println(t2 - t1);
	System.out.println(t3 - t2);
    }
}

Results

15 ms, append() String argument
 7 ms, append() char argument

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

StringBuffer. Это более старая версия StringBuilder. Эти два класса почти одинаковы, за исключением того, что StringBuffer является потокобезопасным и несколько медленнее.

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

Оцени статью

Средняя оценка / 5. Количество голосов:

Спасибо, помогите другим - напишите комментарий, добавьте информации к статье.

Или поделись статьей

Видим, что вы не нашли ответ на свой вопрос.

Помогите улучшить статью.

 

Пока нет комментариев.

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

Ваш e-mail не будет опубликован.

СайдбарКомментарии (0)