deleteCharAt или setLength, какой способ лучше удалить последний символ из StringBuilder / StringBuffer

во многих случаях нам нужно удалить последний символ StringBuilder / StringBuffer. Например,int[]{1,2,3} для реализации String toString(int[] a) метод, контактирующий с каждым элементом с разделителем запятой. Выход должен быть 1,2,3, нет хвостовых запятой.

мы можем легко написать цикл:

int[] nums = new int[]{1,2,3,4,5};
StringBuilder sb = new StringBuilder();
for (int i = 0; i < nums.length; i++) {
    sb.append(nums[i]);
    sb.append(",");
}
//here we need to remove the tailing ','

но всегда нам нужно удалить хвост ','. Существует два способа его реализации:

sb.deleteCharAt(sb.length() - 1);

и

sb.setLength(sb.length() - 1);

какой из них рекомендуется? Почему?

Примечание.: Я знаю, что делает Arrays.toString do. Это просто пример, чтобы описать мой вопрос, может быть не совсем правильным. это не Обсуждение конкатенации строк, а лучшие практики StringBuffer / StringBuilder.

3 ответов


на самом деле, в нем очень мало и, вероятно, зависит от аппаратных и других факторов.

на setLength() метод просто изменяет количество и перезаписывает нежелательное значение в массиве с нулевым байтом.

на deleteCharAt() выполняет внутреннюю копию массива перед изменением количества. Это звучит драматично, но копируемый массив на самом деле имеет нулевую длину, потому что вы удаляете последний символ.

Я бы рекомендовал пойти на setLength() Как это короче печатать, и я думаю, что делает его более ясным, что вы делаете. Если производительность является проблемой, и при измерении вы обнаружите, что это узкое место для вас, тогда, возможно, вы могли бы рассмотреть другой алгоритм, который не требует изменения размера (согласно ответу JB Nizet).


Как вы это делаете правильно, чтобы условно добавить запятую:

for (int i = 0; i < nums.length; i++) {
    if (i > 0)
        sb.append(',');
    sb.append(nums[i]);
}

тогда вам не нужно беспокоиться об удалении последнего символа, потому что это уже исправить.


Я бы так не поступил. Вместо этого я бы добавил только конечную запятую, если элемент не является последним элементом массива. Или я бы использовал Столяр гуавы (или Apache-commons StringUtils), что делает его намного более ясным:

String s = Joiner.on(',').join(nums);

NB: я только что заметил, что столяр Guava не имеет дело с примитивными массивами. В любом случае, вы должны получить идею из вышесказанного.