Vous avez des améliorations (ou des corrections) à proposer pour ce document :
je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Cette classe permet de produire une chaîne de caractères nécessitant d'agréger une grande quantité d'informations.
Concaténer des chaînes de caractères (via les opérateurs + ou +=) dans des boucles peut s'avérer très couteûx en temps.
De nombreux objets temporaires (de type String) sont produits, ce qui fait forcer le garbage collector, et les recopies des caractères d'une chaîne
à l'autre vont être nombreuses et couteûses. Plutôt que d'utiliser des concaténations, il vous est suggéré d'utiliser un StringBuilder
qui permet de limiter les allocations mémoire et les recopies de chaînes. Une fois toutes les informations injectées dans votre builder, vous pourrez
produire la chaîne finale en invoquant la méthode toString.
contrairement à une instance de String qui, je le rappelle, est non modifiable, une instance de type StringBuilder peut
être modifiée à tout moment.
Comme son nom l'indique, la classe implémente le « design pattern Builder ». Dit autrement, les méthodes d'enrichissements de la chaîne à produire
renvoit systématiquement le builder en cours d'utilisation. Il est donc possible d'enchaîner les appels de méthodes comme le montre l'exemple suivant.
1
2
3
4
5
6
7
// On peut enchaîner les appels de méthodes
builder.append( "Début" ).append( numericData ).append( "Fin" );
// La ligne précédente est équivalente à :
builder.append( "Début" );
builder.append( numericData );
builder.append( "Fin" );
On peut enchaîner les traitements
la classe StringBuilder n'est pas « thread safe ». Si plusieurs threads travaillent simultanément sur une même instance de
StringBuilder, le résultat final sera non prévisible. Si vous travaillez dans un environnement multi-threads, il vous est conseillé de
privilégier l'utilisation de la classe StringBuffer qui, elle, est thread safe.
Exemple de code
Voici un exemple d'utilisation de la classe StringBuilder : on y produit le code HTML d'un tableau constitué de plusieurs lignes et de plusieurs
cellules de données. Un comparatif, en termes de temps d'exécution, y est réalisé avec des concaténations plus classiques.
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.util.Date;
publicclass HtmlGenerator {
privatestaticfinalint LOOP_COUNT = 2000;
// On génère le code HTML d'un tableau avec des concaténations.publicstatic String simpleGeneration() {
String temp = "<table class='sample'>";
for( int rowIndex=0; rowIndex<10; rowIndex++ ) {
temp += "<tr>";
for( int columnIndex=0; columnIndex<10; columnIndex++ ) {
temp += "<td>Cell " + columnIndex + "x" + rowIndex + "</td>";
}
temp += "</tr>";
}
temp += "</table>";
return temp;
}
// On génère le code HTML d'un tableau avec un StringBuilder.publicstatic String optimizedGeneration() {
StringBuilder temp = new StringBuilder( "<table class='sample'>" );
for( int rowIndex=0; rowIndex<10; rowIndex++ ) {
temp.append( "<tr>" );
for( int columnIndex=0; columnIndex<10; columnIndex++ ) {
temp.append( "<td>Cell " );
temp.append( columnIndex ).append( "x" ).append( rowIndex );
temp.append( "</td>" );
}
temp.append( "</tr>" );
}
temp.append( "</table>" );
return temp.toString();
}
// On compare les deux approches pour voir laquelle est la plus performante.publicstaticvoid main(String[] args) {
long begin = System.currentTimeMillis();
for( int i=0; i<LOOP_COUNT; i++ ) {
HtmlGenerator.simpleGeneration();
}
long end = System.currentTimeMillis();
System.out.println( "Simple generation time " + (end-begin) + "ms" );
begin = System.currentTimeMillis();
for( int i=0; i<LOOP_COUNT; i++ ) {
HtmlGenerator.optimizedGeneration();
}
end = System.currentTimeMillis();
System.out.println( "Optimized generation time " + (end-begin) + "ms" );
}
}
Exemple d'utilisation d'un StringBuilder
Et voici les résultats produit sur mon PC : les temps peuvent changer en fonction de la puissance de calcul de votre machine, mais dans tous les
cas, l'approche utilisant un StringBuilder sera plus efficace.
Simple generation time 229ms
Optimized generation time 15ms
Améliorations / Corrections
Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.
Emplacement :
Description des améliorations :