¿Eliminar el último carácter de un StringBuilder?
Cuando tienes que recorrer una colección y crear una cadena de cada dato separado por un delimitador, siempre terminas con un delimitador adicional al final, por ejemplo
for (String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
Da algo como: serverId_1, serverId_2, serverId_3,
Me gustaría eliminar el último carácter en StringBuilder (sin convertirlo porque todavía lo necesito después de este bucle).
Otros han señalado el deleteCharAt
método, pero aquí hay otro enfoque alternativo:
String prefix = "";
for (String serverId : serverIds) {
sb.append(prefix);
prefix = ",";
sb.append(serverId);
}
Alternativamente, usa la Joiner
clase de Guava :)
A partir de Java 8, StringJoiner
forma parte del estándar JRE.
Otra solución sencilla es:
sb.setLength(sb.length() - 1);
Una solución más complicada:
La solución anterior supone que sb.length() > 0
... es decir, hay un "último carácter" que eliminar. Si no puede hacer esa suposición, y/o no puede lidiar con la excepción que se produciría si la suposición es incorrecta, primero verifique la longitud de StringBuilder; p.ej
// Readable version
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
o
// Concise but harder-to-read version of the above.
sb.setLength(Math.max(sb.length() - 1, 0));
if(sb.length() > 0){
sb.deleteCharAt(sb.length() - 1);
}
A partir de Java 8, la clase String tiene un método estático join
. El primer argumento es una cadena que desea entre cada par de cadenas, y el segundo es Iterable<CharSequence>
(que son ambas interfaces, por lo que algo como List<String>
funciona. Entonces puede hacer esto:
String.join(",", serverIds);
También en Java 8, puede usar la nueva StringJoiner
clase, para escenarios en los que desea comenzar a construir la cadena antes de tener la lista completa de elementos para colocar en ella.
Simplemente obtenga la posición del último carácter que apareció.
for(String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
sb.deleteCharAt(sb.lastIndexOf(","));
Dado que lastIndexOf
realizará una búsqueda inversa y usted sabe que encontrará en el primer intento, el rendimiento no será un problema aquí.
EDITAR
Dado que sigo recibiendo preguntas sobre mi respuesta (gracias amigos 😊), vale la pena tener en cuenta eso:
En Java 8 en adelante, sería más legible y explícito usar StringJoiner . Tiene un método para un separador simple y una sobrecarga para prefijo y sufijo.
Ejemplos tomados de aquí: ejemplo
Ejemplo usando separador simple:
StringJoiner mystring = new StringJoiner("-");
// Joining multiple strings by using add() method
mystring.add("Logan");
mystring.add("Magneto");
mystring.add("Rogue");
mystring.add("Storm");
System.out.println(mystring);
Producción:
Logan-Magneto-Rogue-Tormenta
Ejemplo con sufijo y prefijo:
StringJoiner mystring = new StringJoiner(",", "(", ")");
// Joining multiple strings by using add() method
mystring.add("Negan");
mystring.add("Rick");
mystring.add("Maggie");
mystring.add("Daryl");
System.out.println(mystring);
Producción
(Negan, Rick, Maggie, Daryl)
En este caso,
sb.setLength(sb.length() - 1);
es preferible ya que simplemente asigna el último valor, '\0'
mientras que eliminar el último carácter sí lo hace.System.arraycopy