Je viens de rencontrer StringBuilder
pour la première fois et j'ai été surpris car Java possède déjà une classe String
très puissante qui permet l'ajout.
Pourquoi une deuxième classe String
?
Où puis-je en savoir plus sur StringBuilder
?
String
ne permet pas l'ajout. Chaque méthode que vous invoquez sur un String
crée un nouvel objet et le renvoie. C'est parce que String
est immuable - il ne peut pas changer son état interne.
D'un autre côté, StringBuilder
est modifiable. Lorsque vous appelez append(..)
, cela modifie le tableau de caractères interne, plutôt que de créer un nouvel objet chaîne.
Il est donc plus efficace d'avoir:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 500; i ++) {
sb.append(i);
}
plutôt que str += i
, ce qui créerait 500 nouveaux objets chaîne.
Notez que dans l'exemple, j'utilise une boucle. Comme le note Helios dans les commentaires, le compilateur traduit automatiquement des expressions comme String d = a + b + c
à quelque chose comme
String d = new StringBuilder(a).append(b).append(c).toString();
Notez également qu'il existe StringBuffer
en plus de StringBuilder
. La différence est que le premier a des méthodes synchronisées. Si vous l'utilisez comme variable locale, utilisez StringBuilder
. S'il arrive qu'il soit possible d'y accéder par plusieurs threads, utilisez StringBuffer
(c'est plus rare)
Voici un exemple concret expliquant pourquoi -
int total = 50000;
String s = "";
for (int i = 0; i < total; i++) { s += String.valueOf(i); }
// 4828ms
StringBuilder sb = new StringBuilder();
for (int i = 0; i < total; i++) { sb.append(String.valueOf(i)); }
// 4ms
Comme vous pouvez le voir, la différence de performances est significative.
La classe de chaîne est immuable tandis que StringBuilder est mutable.
String s = "Hello";
s = s + "World";
Le code ci-dessus créera deux objets car la chaîne est immuable
StringBuilder sb = new StringBuilder("Hello");
sb.append("World");
Le code ci-dessus ne créera qu'un seul objet car StringBuilder n'est pas immuable.
Leçon: Chaque fois qu'il est nécessaire de manipuler/mettre à jour/ajouter de la chaîne à plusieurs reprises, optez pour StringBuilder comme étant efficace par rapport à String.
StringBuilder est, enfin, pour la construction de chaînes. Plus précisément, les construire de manière très performante. La classe String est bonne pour beaucoup de choses, mais elle a en fait des performances vraiment terribles lors de l'assemblage d'une nouvelle chaîne à partir de parties de chaîne plus petites car chaque nouvelle chaîne est une chaîne totalement nouvelle et réallouée. (C'est immuable) StringBuilder garde la même séquence en place et la modifie ( mutable).
La classe StringBuilder est modifiable et contrairement à String, elle vous permet de modifier le contenu de la chaîne sans avoir besoin de créer plus d'objets String, ce qui peut être un gain de performances lorsque vous modifiez fortement une chaîne. Il existe également un équivalent pour StringBuilder appelé StringBuffer qui est également synchronisé, il est donc idéal pour les environnements multithread.
Le plus gros problème avec String est que toute opération que vous effectuez avec elle retournera toujours un nouvel objet, par exemple:
String s1 = "something";
String s2 = "else";
String s3 = s1 + s2; // this is creating a new object.
Efficacité.
Chaque fois que vous concaténerez des chaînes, une nouvelle chaîne sera créée. Par exemple:
String out = "a" + "b" + "c";
Cela crée une nouvelle chaîne temporaire, y copie "a" et "b" pour aboutir à "ab". Ensuite, il crée une autre nouvelle chaîne temporaire, y copie "ab" et "c", pour aboutir à "abc". Ce résultat est ensuite affecté à out
.
Le résultat est un algorithme de Schlemiel le peintre de complexité temporelle O (n²) (quadratique).
StringBuilder
, d'autre part, vous permet d'ajouter des chaînes sur place, en redimensionnant la chaîne de sortie si nécessaire.
StringBuilder est bon lorsque vous traitez avec des chaînes plus grandes. Il vous aide à améliorer les performances.
Voici un article que j'ai trouvé utile.
Une recherche rapide sur Google aurait pu vous aider. Maintenant, vous avez embauché 7 personnes différentes pour effectuer une recherche Google pour vous. :)
Pour être précis, StringBuilder ajoutant toutes les chaînes est O(N) tandis que l'ajout de String est O (N ^ 2). En vérifiant le code source, cela est réalisé en interne en conservant un tableau mutable de caractères. StringBuilder utilise la technique de duplication de la longueur du tableau pour atteindre les performances ammortized O (N ^ 2), au prix d'un doublement potentiel de la mémoire requise. Vous pouvez appeler trimToSize à la fin pour résoudre ce problème, mais généralement les objets StringBuilder ne sont utilisés que temporairement. Vous pouvez encore améliorer les performances en fournissant une bonne estimation de départ de la taille finale de la chaîne.
Java a String, StringBuffer et StringBuilder:
String: Son immuable
StringBuffer: Son Mutable et ThreadSafe
StringBuilder: Son Mutable mais pas ThreadSafe, introduit dans Java 1.5
Chaîne par exemple:
public class T1 {
public static void main(String[] args){
String s = "Hello";
for (int i=0;i<10;i++) {
s = s+"a";
System.out.println(s);
}
}
}
}
sortie: 10 chaînes différentes seront créées au lieu d'une seule chaîne.
Helloa
Helloaa
Helloaaa
Helloaaaa
Helloaaaaa
Helloaaaaaa
Helloaaaaaaa
Helloaaaaaaaa
Helloaaaaaaaaa
Helloaaaaaaaaaa
StringBuilder par exemple: Un seul objet StringBuilder sera créé.
public class T1 {
public static void main(String[] args){
StringBuilder s = new StringBuilder("Hello");
for (int i=0;i<10;i++) {
s.append("a");
System.out.println(s);
}
}
}
String et StringBuilder sont des classes dans Java mais la différence est que les chaînes sont immuables tandis que les StringBuilders sont mutables. Il existe certaines opérations que String n'offre pas en tant que mais StringBuilder le fait. Voici quelques méthodes StringBuilder:
Pour utiliser les méthodes StringBuilder sur String, vous devez passer String comme argument au constructeur StringBuilder et cela créera une instance StringBuilder
String s = "Your String";
StringBuilder sb = new StringBuilder(s);
Ensuite, vous pouvez utiliser les méthodes StringBuilder suivantes sur StringBuilder Instance sb