Лучшие практики / производительность: смешивание StringBuilder.append с String.concat
Я пытаюсь понять, что является лучшим опытом и почему для объединения строковых литералов и переменных для разных случаев. Например, если у меня есть такой код
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
.append(B_String).append("CCCCCCCCCCC").append(D_String)
.append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
.append("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
Это способ сделать это? Из этого поста я заметил, что +
Оператор Strings создает новый экземпляр StringBuilder, объединяет операнды и возвращает преобразование String, которое кажется гораздо более трудоемким, чем просто вызов .append()
; так что если это правда, то об этом не может быть и речи. Но что насчет String.concat()
? Правильно ли использовать .append()
для каждого объединения? Или только для переменных, и литералы можно добавить с .concat()
?
StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
.append(B_String.concat("CCCCCCCCCCC")).append(D_String
.concat("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
.concat("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));
Каковы общие правила для лучших практик и производительности для решения этих ситуаций? Правильно ли мое предположение о +
а на самом деле его просто нельзя использовать?
7 ответов
+
оператор
String s = s1 + s2
За кулисами это переводится:
String s = new StringBuilder(s1).append(s2).toString();
Представьте, сколько дополнительной работы он добавляет, если у вас есть s1 + s2
Вот:
stringBuilder.append(s1 + s2)
вместо:
stringBuilder.append(s1).append(s2)
Несколько строк с +
Стоит отметить, что:
String s = s1 + s2 + s3 + ... +sN
переводится на:
String s = new StringBuilder(s1).append(s2).append(s3)...apend(sN).toString();
concat()
String s = s1.concat(s2);
String
создает char[]
массив, который может соответствовать как s1
а также s2
, Копии s1
а также s2
содержимое этого нового массива. На самом деле требует меньше работы, чем +
оператор.
StringBuilder.append()
Поддерживает внутренний char[]
массив, который растет при необходимости. Без дополнительных char[]
создается, если внутренний достаточно большой.
stringBuilder.append(s1.concat(s2))
также плохо работает, потому что s1.concat(s2)
создает дополнительный char[]
массив и копии s1
а также s2
чтобы просто скопировать это новое содержимое массива во внутренний StringBuilder
char[]
,
Это, как говорится, вы должны использовать append()
все время и добавляйте необработанные строки (ваш первый фрагмент кода правильный).
Компилятор оптимизирует + конкатенацию.
Так
int a = 1;
String s = "Hello " + a;
превращается в
new StringBuilder().append("Hello ").append(1).toString();
Здесь отличная тема, объясняющая, почему вы должны использовать оператор +.
Оптимизация выполняется автоматически компилятором.
Компилятор Java2 автоматически преобразует следующее:
String s = s1 + s2;
в
String s = (new StringBuffer()).append(s1).append(s2).toString();
Взято прямо с веб-сайта Java Best Practices on Oracles.
Вы должны всегда использовать append
,
concat
создать новую строку, так что это очень похоже на +
Я думаю.
если ты concat
или использовать +
с 2 final String JVM может выполнить оптимизацию, так что это то же самое, что и добавить в этом случае.
Если вы объединяете ровно две строки, используйте String.concat (создает новую строку, создавая новый массив символов, который соответствует обеим строкам и копирует в него массивы обеих строк).
Если вы объединяете несколько (более двух) строк в одну строку, используйте + или StringBuilder.append, это не имеет значения, так как компилятор преобразует + в StringBuilder.append. Это хорошо для нескольких строк, поскольку поддерживает один массив символов, который увеличивается по мере необходимости.
Если вы объединяете несколько строк в несколько строк, создайте один StringBuilder и используйте метод append. В конце концов, когда вы закончите добавление Strings в StringBuilder, используйте его.toString()- метод для создания String из него. Для объединения в несколько строк это быстрее, чем во втором методе, поскольку второй метод будет создавать новый StringBuilder в каждой строке, добавлять строки и затем приводить обратно к String, в то время как третий метод использует только один StringBuilder для всего этого.
Я лично предпочитаю Strings.format()
, простой и удобный форматировщик однострочных строк.
String b = "B value";
String d = "D value";
String fullString = String.format("A %s C %s E F", b, d);
// Output: A B value C D value E F
Использование +
Оператор - лучшая практика, он также прост и читабелен.
Язык Java обеспечивает специальную поддержку оператора конкатенации строк ( +) и преобразования других объектов в строки. Конкатенация строк реализуется с помощью класса StringBuilder(или StringBuffer) и его метода добавления.
Официальный документ: https://docs.oracle.com/javase/8/docs/api/java/lang/String.html
Все ответы довольно хороши и понятны. Но я чувствовал, что изучение других методов конкатенации строк также может помочь, например, Guava Joiner, Streams, String.format и т. Д.
Для получения полной информации о производительности каждого метода конкатенации https://redfin.engineering/java-string-concatenation-which-way-is-best-8f590a7d22a8.
Вкратце, производительность конкатенации зависит от номера. строк для объединения. Например, для объединения 1-10 строк лучше всего подходят эти методы - StringBuilder, StringBuffer и Plus Operator. А для объединения сотен строк - Guava Joiner, библиотека apache stringsUtils также отлично работает.
Просмотрите указанный выше блог. Это действительно очень хорошо объясняет эффективность работы.
Спасибо.
На уровне байт-кода ничего не отличается, и мы не ставим под угрозу эффективность. В случае выполнения уровня байтового кода, он должен пройти через не встроенный метод перегрузки операторов для +, вызвав append. затем на уровне языка ассемблера (Java написана на C, а C производит сборки, аналогичные сборкам, будет дополнительный вызов регистра для вызова store + метода в стеке и будет дополнительный push. (на самом деле, кросс-компилятор может оптимизировать оператор + звоните, в этом случае не делая различий с эффективностью.)
Хорошей практикой является наличие одного способа повысить удобочитаемость.:)