StringBuffer et StringBuilder en Java

08 Sep 2019 08 Sep 2019 10457 vues ESSADDOUKI Mostafa
Introduction
1 Nouveautés de Java 11 2 Différences entre JDK, JRE et JVM 3 Structure d'un programme Java - Hello World 4 Mots clés et conventions de dénomination en Java 5 Types de données intégrés en Java 6 Les variables en Java 7 Classes enveloppe - Number, Integer, Double ... 8 Lire les entrées clavier en Java
Structures de contrôle
9 Les opérateurs en Java 10 Les structures conditionnelles en Java 11 Les boucles en Java 12 Instructions de contrôle de boucle - break, continue
Chaines de caractères
13 Les chaines en Java - API String 14 Les chaines en Java - StringBuffer et StringBuilder 15 Les expressions régulières en Java
Programmation OO
16 Objets et classes en Java 17 Modificateurs d'accès Java - public, private, protected et package 18 Méthodes et surcharge des méthodes en Java 19 les constructeurs en Java 20 L'héritage en Java 21 Classes abstraites en Java 22 Interfaces et héritage multiple en Java 23 Les classes imbriquées en Java 24 Les singletons en Java 25 Classes et méthodes génériques 26 Interface fonctionnelle et expressions Lambda en Java
Tableaux et collections
27 Les tableaux en Java 28 Classe Arrays - java.util.Arrays 29 Les listes dynamiques - java.util.ArrayList 30 Les listes chaînées en Java - java.util.LinkedList 31 HashSet en Java - java.util.HashSet 32 HashMap en Java - java.util.HashMap
Gestion des fichiers
33 Comprendre les fichiers informatiques 34 Utilisation des classes Path et Files en Java 35 Lecture et écriture dans un fichier en Java 36 Fichiers à accès aléatoire en Java
Gestion d'exceptions
37 Gestion d'exceptions en Java 38 Créez vos propres classes d'exception en Java
Programmation concurrente
39 Introduction à la programmation concurrente en Java - Multi-threads 40 classe java.lang.Thread 41 Synchronisation des threads en Java

StringBuffer et StringBuilder en Java

  Prérequis

Maîtriser la classe String et son immuabilité. Comprendre les notions d'objet et de méthode en Java. Avoir des bases sur la notion de thread et de synchronisation (pour distinguer StringBuffer de StringBuilder).

  Objectifs

Comprendre pourquoi et quand utiliser StringBuffer et StringBuilder à la place de String. Maîtriser les méthodes essentielles de modification de chaînes : append, insert, replace, delete, reverse. Savoir choisir entre les trois classes selon le contexte.

1. Rappel — La limite de String

String est immuable — coût en performance Chaque opération sur un String crée un nouvel objet en mémoire. Dans une boucle qui concatène des milliers de chaînes, cela génère autant d'objets temporaires et peut sérieusement dégrader les performances.
String resultat = "";
for (int i = 0; i < 10000; i++) {
    resultat += i;
}
Ce code crée 10 000 objets String intermédiaires. Avec StringBuilder, un seul objet est modifié en place.
Solution — StringBuffer et StringBuilder StringBuffer et StringBuilder sont des classes Java qui représentent des séquences de caractères modifiables. Contrairement à String, leur contenu peut être modifié sans créer de nouveaux objets.

2. StringBuffer vs StringBuilder vs String

Critère String StringBuffer StringBuilder
Modifiable Non (immuable) Oui Oui
Thread-safe Oui (immuable) Oui (synchronisé) Non
Performance Faible si beaucoup de concaténations Moyenne (synchronisation coûteuse) Haute (pas de synchronisation)
Usage recommandé Chaînes fixes, peu de modifications Multithread avec modifications Mono-thread avec nombreuses modifications
Package java.lang java.lang java.lang
Règle pratique Dans la quasi-totalité des cas courants (application mono-thread), utilisez StringBuilder — il est plus rapide que StringBuffer. Réservez StringBuffer aux contextes multithread où plusieurs threads accèdent et modifient la même instance.

3. La classe StringBuffer

Définition — StringBuffer StringBuffer est une classe Java représentant une séquence de caractères modifiable et thread-safe. Ses méthodes sont synchronisées, ce qui garantit un accès sécurisé depuis plusieurs threads simultanément.

3.1 Constructeurs

Constructeur Description
StringBuffer() Crée un tampon vide avec une capacité initiale de 16 caractères
StringBuffer(String str) Crée un tampon initialisé avec la chaîne str
StringBuffer(int capacity) Crée un tampon vide avec la capacité spécifiée

  Complément — Capacité vs Longueur

La longueur (length()) est le nombre de caractères actuellement stockés. La capacité (capacity()) est la taille du tampon interne alloué. La capacité initiale d'un StringBuffer(String s) est s.length() + 16. Quand la capacité est dépassée, Java la double automatiquement.

3.2 Méthodes principales

Méthode Description
append(String s) Ajoute s à la fin. Surchargée pour tous les types (int, char, double…)
insert(int offset, String s) Insère s à la position offset
replace(int start, int end, String str) Remplace les caractères de start à end (exclu) par str
delete(int start, int end) Supprime les caractères de start à end (exclu)
deleteCharAt(int index) Supprime le caractère à l'indice index
reverse() Inverse l'ordre des caractères
charAt(int index) Retourne le caractère à la position index
length() Retourne le nombre de caractères courant
capacity() Retourne la capacité du tampon interne
substring(int begin) Retourne la sous-chaîne à partir de begin
substring(int begin, int end) Retourne la sous-chaîne de begin à end (exclu)
toString() Convertit le StringBuffer en String

  Exemple 1 — Opérations sur StringBuffer

public class TestStringBuffer {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("Developpement Informatique");

        System.out.println("Longueur : " + s.length());
        System.out.println("Capacité : " + s.capacity());

        s.append(".com");
        System.out.println("Après append     : " + s);

        s.insert(13, "-");
        System.out.println("Après insert     : " + s);

        s.reverse();
        System.out.println("Après reverse    : " + s);

        s.delete(0, 5);
        System.out.println("Après delete(0,5): " + s);

        s.deleteCharAt(7);
        System.out.println("Après deleteCharAt(7): " + s);

        s.replace(0, 5, "Meknes");
        System.out.println("Après replace    : " + s);
    }
}
Sortie
Longueur : 26
Capacité : 42
Après append     : Developpement Informatique.com
Après insert     : Developpement- Informatique.com
Après reverse    : moc.euqitamrofnI -tnemeppoleveD
Après delete(0,5): uqitamrofnI -tnemeppoleveD
Après deleteCharAt(7): uqitamrfnI -tnemeppoleveD
Après replace    : MeknesmrfnI -tnemeppoleveD

3.3 Chaînage de méthodes

Chaque méthode modificatrice de StringBuffer retourne l'objet lui-même. Cela permet de chaîner les appels sur une même ligne, rendant le code plus concis.

StringBuffer sb = new StringBuffer();

sb.append("Bonjour")
  .append(", ")
  .append("Java")
  .append(" !")
  .insert(8, "beau ");

System.out.println(sb);
Sortie
Bonjour, beau Java !

3.4 Faits importants sur StringBuffer

Points clés
  • StringBuffer hérite de la classe Object.
  • Elle implémente les interfaces Serializable, Appendable et CharSequence.
  • Ses méthodes sont synchronisées — sûres pour les environnements multithread.
  • Elle hérite de Object les méthodes equals, hashCode, toString, getClass.

4. La classe StringBuilder

Définition — StringBuilder StringBuilder est fonctionnellement identique à StringBuffer mais ses méthodes ne sont pas synchronisées. Elle est donc plus rapide en contexte mono-thread, ce qui couvre la quasi-totalité des cas d'usage courants.
   
Syntaxe — StringBuilder Java
StringBuilder sb = new StringBuilder();
StringBuilder sb = new StringBuilder("texte initial");
StringBuilder sb = new StringBuilder(256);

  Exemple 2 — StringBuilder pour concaténation performante

public class TestStringBuilder {
    public static void main(String[] args) {

        StringBuilder sb = new StringBuilder();

        for (int i = 1; i <= 5; i++) {
            sb.append("item").append(i);
            if (i < 5) sb.append(", ");
        }
        System.out.println(sb);

        sb.insert(0, "[").append("]");
        System.out.println(sb);

        sb.delete(7, 13);
        System.out.println(sb);

        System.out.println("Longueur : " + sb.length());

        String resultat = sb.toString();
        System.out.println("Converti en String : " + resultat);
    }
}
Sortie
item1, item2, item3, item4, item5
[item1, item2, item3, item4, item5]
[item1, item3, item4, item5]
Longueur : 28
Converti en String : [item1, item3, item4, item5]

4.1 StringBuilder et les boucles — comparaison de performance

  Application — Mesure du temps de concaténation

int N = 50_000;

long debut = System.currentTimeMillis();
String s = "";
for (int i = 0; i < N; i++) {
    s += i;
}
long fin = System.currentTimeMillis();
System.out.println("String    : " + (fin - debut) + " ms");

debut = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < N; i++) {
    sb.append(i);
}
fin = System.currentTimeMillis();
System.out.println("StringBuilder : " + (fin - debut) + " ms");
Sortie typique
String        : ~1200 ms
StringBuilder :    ~2 ms
Note — Optimisation du compilateur Le compilateur Java optimise automatiquement les concaténations simples avec + en utilisant StringBuilder en coulisse. Cependant, cette optimisation ne s'applique pas aux concaténations à l'intérieur des boucles. C'est là que l'utilisation explicite de StringBuilder est indispensable.

5. Méthodes communes — Tableau récapitulatif

Méthode Description Exemple
append(x) Ajoute x à la fin sb.append("!")
insert(i, x) Insère x à l'indice i sb.insert(0, "Début: ")
replace(a, b, s) Remplace les caractères [a, b[ par s sb.replace(2, 5, "XYZ")
delete(a, b) Supprime les caractères [a, b[ sb.delete(0, 3)
deleteCharAt(i) Supprime le caractère à l'indice i sb.deleteCharAt(5)
reverse() Inverse la séquence sb.reverse()
charAt(i) Retourne le caractère à l'indice i sb.charAt(0)
length() Longueur actuelle sb.length()
capacity() Capacité du tampon sb.capacity()
substring(a) Sous-chaîne de a à la fin sb.substring(3)
substring(a, b) Sous-chaîne de a à b (exclu) sb.substring(2, 6)
indexOf(s) Première occurrence de s sb.indexOf("Java")
toString() Conversion en String immuable sb.toString()

6. Exercice

Construire et manipuler une chaîne avec StringBuilder

Niveau : Débutant

Écrire un programme Java qui utilise StringBuilder pour construire et manipuler une phrase étape par étape.

Travail demandé

  1. Créer un StringBuilder vide.
  2. Ajouter les mots "Java", " est", " un" et " langage" avec append().
  3. Insérer " beau" avant " langage" avec insert().
  4. Remplacer "Java" par "Python" avec replace() (utiliser indexOf() pour trouver la position).
  5. Ajouter un point d'exclamation à la fin.
  6. Afficher la longueur, la capacité et la chaîne finale.
  7. Vérifier si la chaîne finale contient "beau" après conversion en String.
Sortie attendue
Sortie
Après appends  : Java est un langage
Après insert   : Java est un beau langage
Après replace  : Python est un beau langage
Après append ! : Python est un beau langage !
Longueur : 27
Capacité : 34
Contient "beau" : true

  L'essentiel en bref

Là où String est immuable et crée un nouvel objet à chaque modification, StringBuilder et StringBuffer maintiennent un tampon mutable — idéal pour les nombreuses concaténations ou transformations. Les deux partagent la même API : append() pour ajouter, insert() pour insérer, replace() et delete() pour modifier, reverse() pour inverser. La différence clé est la synchronisation : StringBuffer est thread-safe (méthodes synchronisées) au prix de performances moindres, tandis que StringBuilder est plus rapide mais réservé aux contextes mono-thread. En pratique, utilisez toujours StringBuilder sauf si votre code est explicitement multithread. Terminez toujours avec toString() pour récupérer un String immuable standard.