web-dev-qa-db-fra.com

Effacement d'un tampon / constructeur de chaîne après boucle

Comment effacez-vous le tampon de chaîne dans Java après une boucle afin que la prochaine itération utilise un tampon de chaîne vide?

111
waterfallrain

Une option consiste à utiliser la méthode delete comme suit:

StringBuffer sb = new StringBuffer();
for (int n = 0; n < 10; n++) {
   sb.append("a");

   // This will clear the buffer
   sb.delete(0, sb.length());
}

Une autre option (nettoyeur de bits) utilise setLength (int len) :

sb.setLength(0);

Voir Javadoc pour plus d'informations:

129
Jon

Le moyen le plus simple de réutiliser StringBuffer consiste à utiliser la méthode setLength()

public void setLength(int newLength)

Vous pouvez avoir le cas comme

StringBuffer sb = new StringBuffer("HelloWorld");
// after many iterations and manipulations
sb.setLength(0);
// reuse sb
46

Vous avez deux options:

Soit utiliser:

sb.setLength(0);  // It will just discard the previous data, which will be garbage collected later.  

Ou utiliser:

sb.delete(0, sb.length());  // A bit slower as it is used to delete sub sequence.  

REMARQUE

Évitez de déclarer StringBuffer ou StringBuilder objets dans la boucle, sinon cela créera de nouveaux objets à chaque itération. La création d'objets nécessite des ressources système, de l'espace et prend également du temps. Donc, à long terme, évitez si possible de les déclarer dans une boucle.

18
Aditya Singh

Je suggère de créer un nouveau StringBuffer (ou mieux, StringBuilder ) pour chaque itération. La différence de performances est vraiment négligeable, mais votre code sera plus court et plus simple.

5
Eli Acherkan
buf.delete(0,  buf.length());
5
Suraj Chandran
public void clear(StringBuilder s) {
    s.setLength(0);
}

Usage:

StringBuilder v = new StringBuilder();
clear(v);

pour la lisibilité, je pense que c'est la meilleure solution.

4
Ido Kessler

Déjà bonne réponse là-bas. Ajoutez simplement un résultat de référence pour StringBuffer et StringBuild différence de performance, utilisez une nouvelle instance en boucle ou utilisez setLength (0) en boucle.

Le résumé est: Dans une grande boucle

  • StringBuilder est beaucoup plus rapide que StringBuffer
  • Créer une nouvelle instance StringBuilder en boucle n'a aucune différence avec setLength (0). (setLength (0) présente un très très petit avantage que de créer une nouvelle instance.)
  • StringBuffer est plus lent que StringBuilder en créant une nouvelle instance en boucle
  • setLength (0) de StringBuffer est extrêmement lent que la création d'une nouvelle instance en boucle.

Benchmark très simple (je viens de changer le code manuellement et faire un test différent):

public class StringBuilderSpeed {
public static final char ch[] = new char[]{'a','b','c','d','e','f','g','h','i'};

public static void main(String a[]){
    int loopTime = 99999999;
    long startTime = System.currentTimeMillis();
    StringBuilder sb = new StringBuilder();
    for(int i = 0 ; i < loopTime; i++){
        for(char c : ch){
            sb.append(c);
        }
        sb.setLength(0);
    }
    long endTime = System.currentTimeMillis();
    System.out.println("Time cost: " + (endTime - startTime));
}

}

Nouvelle instance de StringBuilder en boucle: coût en temps: 3693, 3862, 3624, 3742

StringBuilder setLength: Coût en temps: 3465, 3421, 3557, 3408

Nouvelle instance de StringBuffer en boucle: coût en temps: 8327, 8324, 8284

StringBuffer setLength Coût en temps: 22878, 23017, 22894

Encore une fois, StringBuilder setLength pour s’assurer que mon laboratoire n’a pas eu le même problème à utiliser si long pour StringBuffer setLength :-) Coût en temps: 3448

1
Hao
StringBuffer sb = new SringBuffer();
// do something wiht it
sb = new StringBuffer();

je pense que ce code est plus rapide.

0
Binh Phung