web-dev-qa-db-fra.com

Supprimer le dernier caractère d'un StringBuilder?

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).

378
Matthew

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.

585
Jon Skeet

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));
388
Stephen C
sb.deleteCharAt(sb.length() - 1) 
164
bragboy

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.

58
ArtOfWarfare

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

34

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)

31
Reuel Ribeiro

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
12
CoderCroc

Une autre alternative

for(String serverId : serverIds) {
   sb.append(",");
   sb.append(serverId); 
}
sb.deleteCharAt(0);
10
Rafiq

Alternativement

StringBuilder result = new StringBuilder();
for(String string : collection) {
    result.append(string);
    result.append(',');
}
return result.substring(0, result.length() - 1) ;
8
Zaki
StringBuilder sb = new StringBuilder();
sb.append("abcdef");
sb.deleteCharAt(sb.length() - 1);
assertEquals("abcde",sb.toString());
// true
5
Antoine

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();
}
5
Jason Day

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);
            }
3
NickUnuchek

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"
1
oguzhan

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(", ");
        }
    }
1
VicJordan

Voici une autre solution:

for(String serverId : serverIds) {
   sb.append(",");
   sb.append(serverId); 
}

String resultingString = "";
if ( sb.length() > 1 ) {
    resultingString = sb.substring(1);
}
0
Stephan

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:

  • le mode d'affichage de \b dépend de l'environnement,
  • la 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.

0
Attacktive