2014-02-08 11 views
12

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

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

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. Это всего лишь пример, чтобы описать мой вопрос, может быть, не совсем правильно. Это не обсуждение конкатенации строк, а лучшие практики StringBuffer/StringBuilder.

+0

Что случилось с 'Arrays.toString (nums)'? а затем удалите первый и последний символы. Но хороший вопрос об общем использовании. –

+0

@tintinmj: Соглашайтесь с вами. Я отредактировал свой вопрос. –

+0

Я выяснил очень близкий вопрос к вам на [CodeReview.SE] (http://codereview.stackexchange.com/questions/37309/perform-instruction-in-loop-every-time-except-the-last-time). –

ответ

13

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

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

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

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

+2

* более короткий тип * не является проблемой, если вы используете какую-либо среду IDE. –

+2

ОК, это более короткое время для чтения. –

+1

+1: обе имеют незначительную стоимость. Используйте то, что вы найдете более ясным для вас. –

1

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

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

NB: Я просто заметил, что Столяр гуавы в не занимается примитивными массивами. Вы все равно должны получить эту идею.

+0

Благодарим вас за ответ. Но это не дискуссия о контакте строк, а лучшие практики StringBuffer/StringBuilder. –

+1

Для меня лучше всего избегать добавления вещей, которые, как вы знаете, вам придется удалить после. Может быть, вы должны придумать вариант использования, где это действительно необходимо. Я не помню, чтобы это делалось в годы программирования на Java. –

2

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^