Lorsque vous devez parcourir une collection et créer une chaîne de chaque donnée séparée par un délimiteur, vous vous retrouvez toujours avec un délimiteur supplémentaire à la fin, par ex.
for (String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
Donne quelque chose comme: serverId_1, serverId_2, serverId_3,
Je voudrais supprimer le dernier caractère de StringBuilder (sans le convertir car j'en ai toujours besoin après cette boucle).
D'autres ont souligné la méthode deleteCharAt
, mais voici une autre approche:
String prefix = "";
for (String serverId : serverIds) {
sb.append(prefix);
prefix = ",";
sb.append(serverId);
}
Vous pouvez également utiliser la classe Joiner
de Guava :)
À partir de Java 8, StringJoiner
fait partie de la norme JRE.
Une autre solution simple est:
sb.setLength(sb.length() - 1);
Une solution plus compliquée:
La solution ci-dessus suppose que sb.length() > 0
... c’est-à-dire qu’il reste un "dernier caractère" à supprimer. Si vous ne pouvez pas faire cette hypothèse et/ou vous ne pouvez pas gérer l'exception qui s'ensuivrait si l'hypothèse est incorrecte, vérifiez d'abord la longueur du StringBuilder; par exemple.
// Readable version
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
ou
// Concise but harder-to-read version of the above.
sb.setLength(Math.max(sb.length() - 1, 0));
sb.deleteCharAt(sb.length() - 1)
A partir de Java 8, la classe String a une méthode statique join
. Le premier argument est une chaîne que vous voulez entre chaque paire de chaînes et le second est un Iterable<CharSequence>
(qui sont les deux interfaces, donc quelque chose comme List<String>
fonctionne. Vous pouvez donc faire ceci:
String.join(",", serverIds);
Également dans Java 8, vous pouvez utiliser la nouvelle classe StringJoiner
, pour les scénarios dans lesquels vous souhaitez commencer à construire la chaîne avant de disposer de la liste complète des éléments à y insérer.
Dans ce cas,
sb.setLength(sb.length() - 1);
est préférable car il suffit d'assigner la dernière valeur à '\0'
alors que la suppression du dernier caractère ne fait que System.arraycopy
Obtenez juste la position de la dernière occurrence de caractère.
for(String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
sb.deleteCharAt(sb.lastIndexOf(","));
Puisque lastIndexOf
effectuera une recherche inversée et que vous saurez qu'elle le trouvera du premier coup, les performances ne seront pas un problème ici.
EDIT
Depuis que je continue à avoir des réponses sur ma réponse (merci les gens ????), il est intéressant à ce sujet:
À partir de Java 8 , il serait simplement plus lisible et plus explicite d’utiliser StringJoiner . Il possède une méthode pour un séparateur simple et une surcharge pour les préfixes et suffixes.
Exemples pris ici: exemple
Exemple d'utilisation du séparateur 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);
Sortie:
Logan-Magneto-Rogue-Storm
Exemple avec suffixe et préfixe:
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);
Sortie
(Negan, Rick, Maggie, Daryl)
Avec Java-8
, vous pouvez utiliser la méthode statique de String
class,
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));
}
}
SORTIE
James,Harry,Roy
Une autre alternative
for(String serverId : serverIds) {
sb.append(",");
sb.append(serverId);
}
sb.deleteCharAt(0);
Alternativement
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
Encore une autre alternative:
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();
}
Pour éviter de réinitialiser (affecter les performances) de prefix
, utilisez TextUtils.isEmpty:
String prefix = "";
for (String item : list) {
sb.append(prefix);
if (TextUtils.isEmpty(prefix))
prefix = ",";
sb.append(item);
}
Vous pouvez essayer d'utiliser la classe 'Joiner' au lieu de supprimer le dernier caractère de votre texte généré;
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"
Je fais quelque chose comme ci-dessous:
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < value.length; i++) {
stringBuilder.append(values[i]);
if (value.length-1) {
stringBuilder.append(", ");
}
}
Voici une autre solution:
for(String serverId : serverIds) {
sb.append(",");
sb.append(serverId);
}
String resultingString = "";
if ( sb.length() > 1 ) {
resultingString = sb.substring(1);
}
Personnellement, j'aime bien ajouter un caractère de retour arrière (ou plus pour un "délimiteur" plus long) à la fin:
for(String serverId : serverIds) {
sb.append(serverId);
sb.append(",");
}
sb.append('\b');
Notez qu'il a des problèmes:
\b
dépend de l'environnement,length()
du contenu String
peut être différente de la longueur des caractères "visibles"Lorsque \b
semble correct et que la longueur n'a pas d'importance, par exemple la connexion à une console, cela me semble suffisant.