Удалить последний символ из класса StringBuilder?
когда вам нужно пройти через коллекцию и сделать строку из каждых данных, разделенных разделителем, вы всегда получаете дополнительный разделитель в конце, например
for(String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
дает что-то типа : serverId_1, serverId_2, serverId_3,
Я хотел бы удалить последний символ в StringBuilder (без преобразования его, потому что он мне все еще нужен после этого цикла).
16 ответов:
другие указали на
deleteCharAt
метод, но вот еще один альтернативный подход:String prefix = ""; for (String serverId : serverIds) { sb.append(prefix); prefix = ","; sb.append(serverId); }
начиная с Java 8,
StringJoiner
является частью стандартного JRE.
еще одно простое решение:
sb.setLength(sb.length() - 1);
более сложное решение:
вышеуказанное решение предполагает, что
sb.length() > 0
... т. е. есть "последний символ" для удаления. Если вы не можете сделать это предположение, и/или вы не можете иметь дело с исключением, которое возникло бы, если предположение неверно, то сначала проверьте длину StringBuilder; например// Readable version if (sb.length() > 0) { sb.setLength(sb.length() - 1); }
или
// Concise but harder-to-read version of the above. sb.setLength(Math.max(sb.length() - 1, 0));
начиная с Java 8, класс String имеет статический метод
join
. Первый аргумент-это строка, которую вы хотите между каждой парой строк, а второй -Iterable<CharSequence>
(которые являются оба интерфейса, что-то вродеList<String>
строительство. Так что вы можете просто сделать это:String.join(",", serverIds);
также в Java 8, вы можете использовать новый
StringJoiner
класс, для сценариев, в которых вы хотите начать построение строки, прежде чем у вас будет полный список элементов для ввода оно.
В этом случае
sb.setLength(sb.length() - 1);
предпочтительнее, так как он просто присваивает последнее значение
''
в то время как удаление последнего символа делаетSystem.arraycopy
просто получить позицию последнего вхождения символа.
for(String serverId : serverIds) { sb.append(serverId); sb.append(","); } sb.deleteCharAt(sb.lastIndexOf(","));
С
lastIndexOf
выполнит обратный поиск, и вы знаете, что он найдет с первой попытки, производительность здесь не будет проблемой.
другая альтернатива
for(String serverId : serverIds) { sb.append(","); sb.append(serverId); } sb.deleteCharAt(0);
С
Java-8
вы можете использовать статический методString
класса,
String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements)
.
public class Test { public static void main(String[] args) { List<String> names = new ArrayList<>(); names.add("James"); names.add("Harry"); names.add("Roy"); System.out.println(String.join(",", names)); } }
выход
James,Harry,Roy
кроме того,
StringBuilder result = new StringBuilder(); for(String string : collection) { result.append(string); result.append(','); } return result.substring(0, result.length() - 1) ;
StringBuilder sb = new StringBuilder(); sb.append("abcdef"); sb.deleteCharAt(sb.length() - 1); assertEquals("abcde",sb.toString()); // true
еще один вариант:
public String join(Collection<String> collection, String seperator) { if (collection.isEmpty()) return ""; Iterator<String> iter = collection.iterator(); StringBuilder sb = new StringBuilder(iter.next()); while (iter.hasNext()) { sb.append(seperator); sb.append(iter.next()); } return sb.toString(); }
чтобы избежать reinit (влияет на производительность)
prefix
использовать TextUtils.отсутствуют:String prefix = ""; for (String item : list) { sb.append(prefix); if (TextUtils.isEmpty(prefix)) prefix = ","; sb.append(item); }
мне лично нравится добавлять символ backspace (или больше для более длинного "разделителя") в конце:
for(String serverId : serverIds) { sb.append(serverId); sb.append(","); } sb.append('\b');
обратите внимание, что у него есть проблемы:
- как
\b
отображается в зависимости от окружающей среды,- the
length()
наString
содержимое может отличаться от длины символов "visibile", когда
\b
выглядит нормально, и длина не имеет значения, например, вход в консоль, это кажется достаточно хорошим, чтобы мне.
вы можете попробовать использовать класс 'Joiner' вместо удаления последнего символа из сгенерированного текста;
List<String> textList = new ArrayList<>(); textList.add("text1"); textList.add("text2"); textList.add("text3"); Joiner joiner = Joiner.on(",").useForNull("null"); String output = joiner.join(textList); //output : "text1,text2,text3"