String
String: строковая константа, длина строки неизменяема. В Java String неизменяем.
Класс String содержит следующее определение:
/** The value is used for character storage. */ private final char value[]; /** The offset is the first index of the storage that is used. */ private final int offset; /** The count is the number of characters in the String. */ private final int count;
Массив, используемый для хранения символов, объявлен как final, поэтому ему можно присвоить значение только один раз, и его нельзя изменить снова.
StringBuffer(JDK1.0)
StringBuffer: строковая переменная (Synchronized, т. е. потокобезопасная). Если вам нужно часто изменять содержимое строки, из соображений эффективности лучше всего использовать StringBuffer. Если вы хотите преобразовать её в тип String, можно вызвать метод toString() класса StringBuffer.
Java.lang.StringBufferПотокобезопасная изменяемая последовательность символов. В любой момент времени она содержит некоторую конкретную последовательность символов, но длину и содержимое последовательности можно изменять с помощью определённых вызовов методов. Строковые буферы можно безопасно использовать из нескольких потоков.
StringBufferОсновные операции с ним — методы append и insert, которые можно перегружать для приёма данных любого типа. Каждый метод фактически преобразует переданные данные в строку, а затем добавляет или вставляет символы этой строки в строковый буфер.
- Метод append всегда добавляет эти символы в конец буфера;
- метод insert добавляет символы в указанную позицию.
Например, еслиzссылается на объект строкового буфера, текущее содержимое которого —start, то этот вызов методаz.append("le")приведёт к тому, что строковый буфер будет содержатьstartle, иz.insert(4, "le")изменит строковый буфер так, что он будет содержатьstarlet 。
StringBuilder(JDK5.0)
StringBuilder: строковая переменная (не потокобезопасная). Внутри объект StringBuilder рассматривается как массив переменной длины, содержащий последовательность символов.
java.lang.StringBuilder — это изменяемая последовательность символов, впервые добавленная в JDK 5.0. Этот класс предоставляет API, совместимый с StringBuffer, но не гарантирует синхронизацию. Этот класс предназначен для использования в качестве простой замены StringBuffer, когда строковый буфер используется одним потоком (эта ситуация очень распространена).
Его конструкторы следующие:
| Конструктор | Описание |
| StringBuilder() | Создаёт объект StringBuilder с ёмкостью 16 (16 пустых элементов) |
| StringBuilder(CharSequence cs) | Создает объект StringBuilder, содержащий cs, с 16 пустыми элементами, добавленными в конец |
| StringBuilder(int initCapacity) | Создает объект StringBuilder с емкостью initCapacity |
| StringBuilder(String s) | Создает объект StringBuilder, содержащий s, с 16 пустыми элементами, добавленными в конец |
В большинстве случаев,StringBuilder > StringBuffer. Это в основном потому, что первому не нужно учитывать потокобезопасность.
Различия между этими тремя
Основное различие в производительности между типом String и StringBuffer: String — неизменяемый объект, поэтому каждый раз, когда тип String изменяется, создается новый объект String, и затем указатель направляется на новый объект String. Следовательно, для строк, содержимое которых часто меняется, не следует использовать String, потому что создание объекта каждый раз влияет на производительность системы, особенно когда в памяти много объектов без ссылок, сборщик мусора JVM начинает работать, и производительность снижается.
При использовании класса StringBuffer операции каждый раз выполняются над самим объектом StringBuffer, а не порождают новые объекты и изменяют ссылки на объекты. Поэтому в большинстве случаев рекомендуется StringBuffer, особенно когда строковые объекты часто изменяются.
В некоторых особых случаях конкатенация строк объектов String фактически компилируется компилятором Java в конкатенацию объектов StringBuffer, поэтому в таких случаях объекты String не медленнее объектов StringBuffer, например:
String s1 = “This is only a” + “ simple” + “ test”; StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);
Скорость создания объекта String s1 не медленнее, чем у StringBuffer. В действительности в компиляторе Java автоматически выполняется следующее преобразование:
Компилятор Java напрямую компилирует первый оператор выше в:
String s1 = “This is only a simple test”;
Таким образом, скорость очень высокая. Но следует отметить, что если объединяемые строки берутся из других объектов String, компилятор Java не преобразует их автоматически, и скорость будет не такой высокой, например:
String s2 = “This is only a”; String s3 = “ simple”; String s4 = “ test”; String s1 = s2 + s3 + s4;
В этом случае компилятор Java будет действовать строго исходным способом. Операция конкатенации String (т. е. +) реализуется с помощью метода append класса StringBuilder (или StringBuffer). В этом случае для описанной выше ситуации, если s2, s3 и s4 определены как String, при конкатенации необходимо создать дополнительный StringBuffer (или StringBuilder), а затем преобразовать StringBuffer в String. Если используется StringBuffer (или StringBuilder), нет необходимости создавать дополнительный StringBuffer.
Стратегии использования
-
(1) Основной принцип: если вы хотите работать с небольшим объёмом данных, используйте String; для однопоточной работы с большими объёмами данных используйте StringBuilder; для многопоточной работы с большими объёмами данных используйте StringBuffer.
-
(2) Не используйте "+" класса String для частой конкатенации, потому что производительность крайне низкая. Следует использовать класс StringBuffer или StringBuilder. Это довольно важный принцип оптимизации Java. Например:
String result = ""; for (String s : hugeArray) { result = result + s; } // 使用StringBuilder StringBuilder sb = new StringBuilder(); for (String s : hugeArray) { sb.append(s); } String result = sb.toString();Когда возникает описанная выше ситуация, очевидно, следует использовать второй способ, потому что в первом способе каждый цикл будетсоздавать результат String для сохранения результата. Помимо этого, оба способа в основном одинаковы (дляJDK 1.5 и более поздних версий)。
-
(3) Для получения лучшей производительности следует по возможности указывать их вместимость при создании StringBuffer или StringBuilder. Конечно, если длина строки, с которой вы работаете, не превышает 16 символов, указывать её не нужно. Если вместимость не указана, по умолчанию создаётся объект с вместимостью 16. Неуказание вместимости значительно снижает производительность.
-
(4) StringBuilder обычно используется внутри методов для выполнения аналогичных+функций. Поскольку он не является потокобезопасным, его можно отбросить после использования. StringBuffer в основном используется для глобальных переменных.
-
(5) При одинаковых условиях использование StringBuilder по сравнению с использованием StringBuffer позволяет достичь повышения производительности лишь примерно на 10%~15%, но это связано с риском отсутствия потокобезопасности. В реальном модульном программировании программист, отвечающий за определённый модуль, может быть не в состоянии точно определить, будет ли модуль выполняться в многопоточной среде. Поэтому: если только вы не уверены, что узким местом системы является StringBuffer, и не уверены, что ваш модуль не будет выполняться в многопоточном режиме, можете использовать StringBuilder; в противном случае по-прежнему используйте StringBuffer.
Источник статьи: https://blog.csdn.net/kingzone_2008/article/details/9220691