Когда вам нужно перебрать коллекцию и сделать строку каждого из данных разделенной разделителем, вы всегда получите дополнительный разделитель в конце, например
for (String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
Дает что-то вроде: serverId_1, serverId_2, serverId_3,
Я хотел бы удалить последний символ в StringBuilder (не преобразовывая его, потому что он мне все еще нужен после этого цикла).
java
stringbuilder
Мэтью
источник
источник
StringJoiner
: stackoverflow.com/a/29169233/901641Ответы:
Другие указали на
deleteCharAt
метод, но вот еще один альтернативный подход:В качестве альтернативы используйте
Joiner
класс из гуавы :)Начиная с Java 8,
StringJoiner
является частью стандарта JRE.источник
Joiner
тоже в ихStringUtils
. commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)Другое простое решение:
Более сложное решение:
Приведенное выше решение предполагает, что
sb.length() > 0
... то есть есть "последний символ", который нужно удалить. Если вы не можете сделать это предположение и / или не можете справиться с исключением, которое возникнет, если это предположение неверно, то сначала проверьте длину StringBuilder; напримерили
источник
источник
sb.length() == 0
такжеseparator.length()
вместо 1.Начиная с Java 8, класс String имеет статический метод
join
. Первый аргумент - это строка, которую вы хотите видеть между каждой парой строк, а второй - этоIterable<CharSequence>
(оба являются интерфейсами, поэтому что-то вродеList<String>
работает. Итак, вы можете просто сделать это:Также в Java 8 вы можете использовать новый
StringJoiner
класс для сценариев, в которых вы хотите начать конструирование строки до того, как у вас будет полный список элементов для ее добавления.источник
String.join
вместоStringJoiner
.Просто получите позицию последнего появления персонажа.
Поскольку
lastIndexOf
обратный поиск будет выполнен, и вы знаете, что он будет найден с первой попытки, производительность здесь не будет проблемой.РЕДАКТИРОВАТЬ
Так как я продолжаю поднимать свой ответ (спасибо, ребята 😊), стоит учитывать следующее:
На Java 8 вперед это только будет более четким и ясным , чтобы использовать StringJoiner . У него есть один метод для простого разделителя и перегрузка для префикса и суффикса.
Примеры взяты отсюда: пример
Пример использования простого разделителя:
Вывод:
Пример с суффиксом и префиксом:
Вывод
источник
,
потому что это было последним утверждениемfor loop
. ЭтоlastInfexOf
больше для удобочитаемости и делает это легким делом, если вы не хотите помнить, индексирован ли он 0 или нет. Кроме того, вам не нужно вмешиваться в длину строителя строки. Это просто для удобства.В этом случае,
предпочтительнее, так как просто присваивает последнее значение,
'\0'
тогда как удаление последнего символаSystem.arraycopy
источник
setLength
Вызов ничего последнего значения не назначая. Строковые буферы Java не заканчиваются нулем / нулем. На самом деле,setLength
просто обновлениеlength
поля.arraycopy
копирует 0 элементов, так что я думаю, что это может быть оптимизировано.С помощью
Java-8
вы можете использовать статический методString
класса,String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements)
,ВЫВОД
источник
Еще одна альтернатива
источник
С другой стороны,
источник
источник
Еще одна альтернатива:
источник
Чтобы избежать переустановки (повлиять на производительность)
prefix
использования TextUtils.isEmpty:источник
Вы можете попытаться использовать класс Joiner вместо удаления последнего символа из вашего сгенерированного текста;
источник
Я делаю что-то вроде ниже:
источник
Вот еще одно решение:
источник
Мне лично нравится добавлять символ возврата (или больше для более длинного «разделителя») в конце:
Обратите внимание, что у него есть проблемы:
\b
отображается зависит от окружающей среды,length()
отString
содержания может отличаться от длины «» символов Записи видныКогда все в
\b
порядке и длина не имеет значения, например, при входе в консоль, мне это кажется достаточно хорошим.источник
stringBuilder.Remove (stringBuilder.Length - 1, 1);
источник