Взаимосвязь и различие между тремя классами String, StringBuilder и StringBuffer всегда были классической проблемой в Java.На этот раз я расскажу о некоторых знаниях об этих трех классах.
1. Простое сравнение
- Строка: символьная константа
- StringBuilder: символьная переменная
- StringBuffer : символьная переменная
String является константным типом и объявляется как окончательный класс, и все свойства также имеют окончательный тип, поэтому после создания объекта String его нельзя изменить; StringBuilder / StringBuffer Эти два класса являются переменными типами и могут быть изменены.Оба класса предназначены для решения проблемы, связанной с тем, что строки создают слишком много промежуточных объектов из-за объединения.
-
Скорость работы StringBuilder> StringBuffer> String
-
Безопасность потоков: StringBuffer
-
Не потокобезопасный: StringBuilder
StringBuilder по сути не сильно отличается от StringBuffer, но поскольку StringBuilder удаляет потокобезопасную часть StringBuffer, он эффективно снижает накладные расходы. следовательно,StringBuilder в большинстве случаев лучше всего подходит для операций конкатенации строк.
2. Строки обработки строк
Пример 1:
String s = "abcd";
s = s + "fgh";
Многие люди делают ошибку, думая, что тип String является изменяемым при выполнении такого рода манипуляций со строками.
Но на самом деле процесс обработки JVM этого кода таков: сначала создайте объект s, присвойте «abcd», а затем при обработке второй строки кода создайте еще один объект s, присвойте «abcdfgh», а затем выбросьте первый объект Recycle.
Так что эквивалентно первому s не изменилось, второе s это новый объект
Пример 2:
String str = “This is only a” + “simple” + “test”;
Этот код эквивалентенString str = “This is only a simple test”;
Пример третий:
String str2 = "This is only a";
String str3 = "simple";
String str4 = "test";
String str1 = str2 +str3 + str4;
Этот код также будет обработан в соответствии с процессом Примера 1.
3. Особенности построения StringBuilder/StringBuffer
В процессе построения этих двух объектов сначала применяется массив символов (char[]) в соответствии с размером по умолчанию, емкость по умолчанию составляет 16 символов, но если она превышает, она будет удвоена с помощью Arrays.copyOf() 16, 32, 64, 128..., конечно, это повлияет на производительность, поэтому вы можете настроить емкость объекта по мере необходимости при его создании.
源代码:
//默认 16 个字符
public StringBuilder() {
super(16);
}
//构造函数定义容量
public StringBuilder(int capacity) {
super(capacity);
}
4. String и StringBuilder, обрабатывающие сравнение сплайсинга строк
Мы все знаем, что StringBuilder рекомендуется для конкатенации строк, но всегда ли рекомендуется использовать StringBuilder вместо String для конкатенации строк? Очевидно нет.
Пример 1:
String str = "123";
String str1 = str + "456";
String str2 = new StringBuilder().append(str).append("def").toString();
В этом случае разница в эффективности двух методов обработки незначительна.
существуетJDK1.5После этого операция конкатенации строк String будет автоматически преобразована компилятором в StringBuilder и вызывается метод append, и, наконец, вызывается метод toString StringBuilder для возврата воссозданной строки.Благодаря этой схеме оптимизации два класса в этом случае разница в эффективности обработки незначительна;Java 9Чтобы унифицировать оптимизацию строковых операций, StringConcatFactory предоставляется как унифицированная запись, которая дополнительно оптимизирует операцию конкатенации строк.
Пример 2:
String str = "";
for (int i = 0; i < 1000; i++) {
str += "12345";
}
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 1000; i++) {
stringBuilder.append("12345");
}
StringBuilder в этом случае быстрее
В цикле каждый раз, когда выполняется «+», будет создан объект String, поэтому будет много потребления создания и повторного использования объекта.
Проще говоря, вв циклеКонкатенация строк одного и того же строкового объекта, предпочтительно StringBuilder
Пример 3
String str1 = "123" + "456" + "789";
String str2 = new StringBuilder("123").append("456").append("789").toString();
Строка быстрее в этом случае
мы все знаемString str1 = "123" + "456" + "789";
на самом деле эквивалентноString str1 = "123456789";
, а StringBuilder вместо этого должен вызывать метод append несколько раз.