Cuando tiene que recorrer una colección y hacer una cadena de cada dato separada por un delimitador, siempre termina con un delimitador adicional al final, por ej.
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 el StringBuilder (sin convertirlo porque todavía lo necesito después de este ciclo).
java
stringbuilder
Mateo
fuente
fuente

StringJoiner: stackoverflow.com/a/29169233/901641Respuestas:
Otros han señalado el
deleteCharAtmétodo, pero aquí hay otro enfoque alternativo:Alternativamente, use la
Joinerclase de Guava :)A partir de Java 8,
StringJoinerforma parte del JRE estándar.fuente
Joineren suStringUtils. commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)Otra solución simple es:
Una solución más complicada:
La solución anterior supone que
sb.length() > 0... es decir, hay un "último carácter" para 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 del StringBuilder; p.ejo
fuente
fuente
sb.length() == 0tambiénseparator.length()lugar de 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 unIterable<CharSequence>(que son ambas interfaces, por lo que algo asíList<String>funciona. Así que puede hacer esto:También en Java 8, podría usar la nueva
StringJoinerclase, para escenarios en los que desea comenzar a construir la cadena antes de tener la lista completa de elementos para incluir.fuente
String.joinlugar de hacerloStringJoiner.Simplemente obtenga la posición de la última aparición del personaje.
Ya que
lastIndexOfque realizará una búsqueda inversa, y sabe que lo encontrará en el primer intento, el rendimiento no será un problema aquí.EDITAR
Dado que sigo recibiendo mi respuesta (gracias amigos 😊), vale la pena considerar 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 el prefijo y el sufijo.
Ejemplos tomados de aquí: ejemplo
Ejemplo usando un separador simple:
Salida:
Ejemplo con sufijo y prefijo:
Salida
fuente
,porque fue la última declaración delfor loop. EstolastInfexOfes más para la legibilidad y para que sea obvio si no desea recordar si está indexado 0 o no. Además, no necesita entrometerse con la longitud del generador de cadenas. Es solo por conveniencia.En este caso,
es preferible ya que solo asigna el último valor a
'\0'mientras que eliminar el último carácterSystem.arraycopyfuente
setLengthllamada no está asignando nada al último valor. Los búferes de cadenas Java no son nulos / terminados en cero. De hecho,setLengthes simplemente actualizar unlengthcampo.arraycopycopia 0 elementos, así que supongo que se puede optimizar.Con
Java-8usted puede usar el método estático deStringclase,String#join(CharSequence delimiter,Iterable<? extends CharSequence> elements).SALIDA
fuente
Otra alternativa
fuente
Alternativamente,
fuente
fuente
Otra alternativa más:
fuente
Para evitar reiniciar (afectar el rendimiento) del
prefixuso TextUtils.isEmpty:fuente
Puede intentar usar la clase 'Joiner' en lugar de eliminar el último carácter del texto generado;
fuente
Estoy haciendo algo como a continuación:
fuente
Aquí hay otra solución:
fuente
Personalmente, me gusta agregar un carácter de retroceso (o más para un "delimitador" más largo al final:
Tenga en cuenta que tiene problemas:
\bse muestra depende del entorno,length()delStringcontenido puede ser diferente de la longitud de caracteres "visibile"Cuando se
\bve bien y la longitud no importa, como iniciar sesión en una consola, esto me parece lo suficientemente bueno.fuente
stringBuilder.Remove (stringBuilder.Length - 1, 1);
fuente