Concaténation de chaînes en Java
Assemblez des chaînes en Java avec l'opérateur +, concat() et StringBuilder, et comparez leurs performances.
La « concaténation » consiste simplement à assembler des chaînes bout à bout. Java propose plusieurs façons de le faire : +, concat, String.format, les blocs de texte, StringBuilder, String.join. Ils diffèrent par leur lisibilité et, dans les boucles, par leurs performances.
L'opérateur +
+ est la manière habituelle :
String first = "Ada";
String last = "Lovelace";
String full = first + " " + last; // "Ada Lovelace"Il convertit également les non-chaînes en chaînes via leur méthode toString() :
int age = 36;
String s = "Age: " + age; // "Age: 36"En coulisse, le compilateur transforme a + b + c en un seul appel StringBuilder.append(...).append(...).toString(). Ainsi, une expression + enchaînée est efficace.
concat
String.concat(other) renvoie cette chaîne suivie de other :
"Hello, ".concat("World!"); // "Hello, World!"C'est effectivement la même chose que +, mais n'accepte qu'une String (pas de conversion automatique). La plupart du code utilise simplement +.
String.format et formatted
Pour la concaténation de plusieurs éléments avec un formatage spécifique au type, String.format est plus lisible que de longues chaînes de + :
String name = "Ada";
int age = 36;
String s = String.format("%s is %d years old", name, age);Depuis Java 15, la méthode d'instance formatted est équivalente et se lit de gauche à droite :
"%s is %d years old".formatted(name, age);Blocs de texte pour le multi-ligne
Pour les chaînes multi-lignes, la syntaxe des blocs de texte (Java 15+) évite les longues chaînes de \n :
String json = """
{
"name": "%s",
"age": %d
}
""".formatted(name, age);StringBuilder — pour les boucles
Les chaînes Java sont immuables — une fois créée, une String ne peut jamais changer. Ainsi, chaque + sur une String produit un nouvel objet. Dans une boucle avec des milliers d'itérations, cela génère beaucoup de courte durée de vie des objets et de copies. Utilisez plutôt StringBuilder — il possède un seul tampon interne mutable qui s'agrandit en place :
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append("line ").append(i).append("\n");
}
String result = sb.toString();Les méthodes de StringBuilder que vous utiliserez :
append(any)— ajouter à la fin (renvoie le builder pour permettre le chaînage).insert(index, any)— insérer à une position.delete(start, end)— supprimer une plage.reverse()— inverser le contenu du builder.length()etsetLength(n)— lire / tronquer.toString()— produire laStringfinale.
Il existe aussi StringBuffer, qui est identique mais thread-safe (chaque méthode est synchronized). Vous en aurez presque jamais besoin — utilisez StringBuilder sauf si vous partagez réellement le builder entre des threads.
String.join — pour les collections
Lorsque vous avez une collection de chaînes et un séparateur, String.join est la solution la plus propre :
String csv = String.join(",", "a", "b", "c"); // "a,b,c"
String csv2 = String.join(", ", List.of("a", "b", "c")); // "a, b, c"Pour un assemblage plus avancé (collecteurs, inclusion conditionnelle), consultez Collectors.joining des streams plus loin dans ce livre.
Quand utiliser quoi
Un arbre de décision simplifié :
- Un ou deux éléments, lisible de gauche à droite →
+. - Plusieurs éléments avec formatage de type →
String.formatouformatted. - Littéral multi-ligne → bloc de texte, éventuellement avec
.formatted. - Construction élément par élément dans une boucle →
StringBuilder. - Assemblage d'une collection avec un séparateur →
String.join.
Pour les petites concaténations, les compilateurs modernes et la JVM (avec la concaténation de chaînes basée sur invokedynamic introduite dans Java 9) rendent + très rapide — les performances ne sont pas une raison de l'éviter pour les cas simples.
Démonstration du cas en boucle
Et ensuite
Caractères spéciaux Java et séquences d'échappement — ce que font \n, \t, \" et les échappements Unicode.