Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 5

Manipulation de chaînes de caractères avec la classe String

Recommended resources

Bonjour ! Dans la leçon précédente, nous avons fait la distinction fondamentale entre les types primitifs et les types référence. Vous savez maintenant que String est un type référence, ce qui signifie qu'une variable de ce type contient une adresse pointant vers un objet en mémoire.

Aujourd'hui, nous allons nous consacrer entièrement à cette classe omniprésente. L'objectif est de maîtriser la manipulation des chaînes de caractères en Java. En tant que futur développeur backend, vous traiterez constamment des données textuelles : requêtes HTTP, données de formulaires, logs, configurations, etc. Bien que vous ayez déjà manipulé des chaînes en JavaScript ou Python, vous découvrirez des particularités propres à Java, notamment son concept d'immutabilité et la manière de comparer les chaînes, qui sont essentiels pour écrire du code correct et performant.

1. La classe String : un objet avant tout

Contrairement à certains langages, en Java, une chaîne de caractères n'est pas un type de base, mais un objet à part entière, une instance de la classe java.lang.String. Cela a des conséquences importantes sur la manière de les créer et de les comparer.

La vidéo suivante introduit très bien ce concept.

Java #13 - chaînes de caractères (1/2)

Regardez ce premier extrait de la vidéo "Java #13 - chaînes de caractères (1/2)" de la chaîne EvoluNoob. Il explique pourquoi String est une classe et montre les deux syntaxes pour créer une instance.

Concentrez-vous sur le passage qui explique la différence entre la syntaxe littérale et l'instanciation explicite avec new. String comme une classe

Comme vous l'avez vu, on peut créer une chaîne de deux manières :

  1. Syntaxe littérale : String s1 = "Bonjour";
  2. Avec le constructeur : String s2 = new String("Bonjour");

Pourquoi cette distinction ? Parce que Java optimise la gestion de la mémoire pour les chaînes créées avec la syntaxe littérale grâce à un mécanisme appelé le "String Pool" (ou réserve de chaînes).

Cette image montre que lorsque vous créez une chaîne avec la syntaxe littérale (comme `s1` et `s3`), Java vérifie si une chaîne identique existe déjà dans le "String Pool". Si oui, il réutilise la même référence. Si vous utilisez `new String()`, un nouvel objet est systématiquement créé dans la mémoire "Heap", en dehors du pool.

Pour approfondir cette différence capitale, la lecture suivante est très éclairante.

Développons en Java - Les chaînes de caractères

Ce document de Jean-Michel Doudoux détaille la différence entre la création par syntaxe littérale et par constructeur, avec des exemples clairs.

Lisez la section "La création d'un objet de type String", et en particulier la sous-section "Syntaxe littérale vs utilisation d'un constructeur". Portez attention aux exemples de code qui utilisent l'opérateur ==.


2. Comparer des chaînes : le piège du ==

Cette gestion via le String Pool nous amène directement à l'une des erreurs les plus fréquentes chez les débutants en Java : la comparaison de chaînes.

Manipulation de chaînes de caractères en Java

Cet article du site Koor.fr explique parfaitement pourquoi il ne faut pas utiliser == pour comparer le contenu des chaînes et comment le faire correctement.

Lisez attentivement la section "Comparaison de chaînes de caractères". Elle met en évidence le comportement de l'opérateur == (qui compare les adresses mémoire) et introduit la méthode equals() (qui compare le contenu). Assurez-vous de bien comprendre l'exemple de code et les résultats affichés.

Pour résumer, voici la règle d'or :

  • Utilisez l'opérateur == uniquement pour vérifier si deux variables de type référence pointent vers le même objet en mémoire.
  • Utilisez la méthode .equals() pour vérifier si deux objets String ont le même contenu, caractère par caractère.
String a = "test"; // Créé dans le String Pool
String b = "test"; // Réutilise l'objet du String Pool
String c = new String("test"); // Force la création d'un nouvel objet dans le Heap

System.out.println(a == b);        // true (les deux pointent vers le même objet dans le pool)
System.out.println(a == c);        // false (a et c sont deux objets différents)
System.out.println(a.equals(c)); // true (le contenu est identique)

Bonne pratique professionnelle : Pour comparer le contenu de deux chaînes, utilisez toujours la méthode .equals(). Si vous voulez ignorer les différences de casse (majuscules/minuscules), la méthode .equalsIgnoreCase() est votre alliée.


3. L'Immutabilité : une caractéristique essentielle de String

Un autre concept fondamental de la classe String en Java est son immutabilité. Cela signifie qu'une fois qu'un objet String est créé, son contenu (la séquence de caractères) ne peut plus jamais être modifié.

"Mais alors," pourriez-vous demander, "comment fonctionnent des méthodes comme toUpperCase() ou replace() ?"

La vidéo suivante répond parfaitement à cette question.

Java #13 - chaînes de caractères (1/2)

Regardez ce deuxième extrait de la vidéo "Java #13 - chaînes de caractères (1/2)". Il explique de manière très visuelle ce que signifie "immuable".

Portez une attention particulière à l'explication de ce qui se passe en mémoire lors d'une "modification". Le concept d'immutabilité

En résumé, toute méthode qui semble "modifier" une chaîne de caractères ne modifie pas l'objet original. Au lieu de cela, elle crée et retourne un nouvel objet String contenant le résultat de la modification.

String s1 = "java";
String s2 = s1.toUpperCase(); // Crée un NOUVEL objet "JAVA"

System.out.println(s1); // Affiche "java" (l'objet original est intact)
System.out.println(s2); // Affiche "JAVA" (s2 pointe vers le nouvel objet)
System.out.println(s1 == s2); // Affiche false (ce sont deux objets distincts)

Cette immutabilité a des avantages (sécurité, prédictibilité dans les environnements multi-thread) mais aussi un inconvénient en termes de performance : si vous effectuez de nombreuses concaténations dans une boucle, vous créez de nombreux objets intermédiaires. Nous verrons plus tard dans le cours des classes comme StringBuilder pour gérer ce cas efficacement.


4. Les méthodes les plus courantes

Maintenant que les concepts clés sont posés, explorons les outils pratiques. La classe String offre une panoplie de méthodes utiles. La vidéo ci-dessous en présente les plus importantes.

Java #13 - chaînes de caractères (1/2)

Ce dernier visionnage de la vidéo "Java #13 - chaînes de caractères (1/2)" vous montrera en action les méthodes les plus utilisées.

Regardez les passages suivants pour voir des exemples concrets : Concaténation : Avec l'opérateur + et la méthode concat(). Méthodes utiles : length(), toUpperCase(), toLowerCase(), trim() et replace(). Accès et extraction : charAt() et substring().

Voici un tableau récapitulatif des méthodes que vous utiliserez le plus souvent :

Catégorie Méthode Description
Inspection length() Renvoie le nombre de caractères.
charAt(int index) Renvoie le caractère à l'index spécifié.
isEmpty() Renvoie true si la chaîne est vide (longueur 0).
isBlank() (depuis Java 11) Renvoie true si la chaîne est vide ou ne contient que des espaces.
Recherche contains(CharSequence s) Renvoie true si la chaîne contient la séquence de caractères spécifiée.
startsWith(String prefix) Vérifie si la chaîne commence par le préfixe spécifié.
endsWith(String suffix) Vérifie si la chaîne se termine par le suffixe spécifié.
indexOf(String str) Renvoie l'index de la première occurrence de la sous-chaîne.
"Modification" substring(int begin, int end) Extrait une sous-chaîne.
(crée une nouvelle chaîne) toLowerCase() / toUpperCase() Convertit la casse.
trim() Supprime les espaces au début et à la fin.
replace(CharSequence old, CharSequence new) Remplace toutes les occurrences d'une sous-chaîne.
Découpage split(String regex) Découpe la chaîne en un tableau (String[]) selon un séparateur.

5. Séquences d'échappement

Parfois, vous devez insérer des caractères spéciaux dans une chaîne, comme un saut de ligne ou des guillemets. Pour cela, on utilise des séquences d'échappement, qui commencent par un anti-slash (\).

Manipulation de chaînes de caractères en Java

Cet extrait de l'article de Koor.fr présente un tableau clair des séquences les plus courantes.

Consultez rapidement la section "Séquences de caractères particulières" pour vous familiariser avec \n, \t, \" et \\.

Exemple :
String cheminFichier = "C:\\Utilisateurs\\MonDossier\\fichier.txt";
String citation = "Il a dit : \"Bonjour !\"";


6. Exercice Pratique

Il est temps de mettre tout cela en pratique !

  1. Ouvrez votre projet dans IntelliJ IDEA.
  2. Dans votre package (fr.votreentreprise.fundamentals), créez une nouvelle classe Java nommée StringManipulationDemo.
  3. Copiez-collez le code suivant dans cette classe et analysez-le. Essayez de prédire la sortie de chaque System.out.println avant d'exécuter le programme.
package fr.votreentreprise.fundamentals; // Adaptez avec votre nom de package

public class StringManipulationDemo {

    public static void main(String[] args) {
        // --- Comparaison ---
        String literal1 = "Java";
        String literal2 = "Java";
        String newObject = new String("Java");

        System.out.println("--- Comparaison ---");
        System.out.println("literal1 == literal2: " + (literal1 == literal2)); // Compare les références
        System.out.println("literal1.equals(newObject): " + literal1.equals(newObject)); // Compare le contenu

        // --- Méthodes courantes ---
        String data = "   id_utilisateur=12345;email=test@exemple.com   ";
        System.out.println("\n--- Manipulation ---");
        System.out.println("Chaîne originale: '" + data + "'");

        // 1. Nettoyer la chaîne (supprimer les espaces au début et à la fin)
        String trimmedData = data.trim();
        System.out.println("Chaîne nettoyée: '" + trimmedData + "'");
        
        // 2. Vérifier si la chaîne contient un email
        boolean hasEmail = trimmedData.contains("@");
        System.out.println("Contient un email: " + hasEmail);

        // 3. Extraire l'ID de l'utilisateur
        // On cherche l'index de '=' et de ';'
        int startIndex = trimmedData.indexOf("=") + 1;
        int endIndex = trimmedData.indexOf(";");
        String userId = trimmedData.substring(startIndex, endIndex);
        System.out.println("ID utilisateur extrait: " + userId);
        
        // 4. Découper la chaîne en paires clé/valeur
        String[] parts = trimmedData.split(";");
        System.out.println("Partie 1: " + parts[0]);
        System.out.println("Partie 2: " + parts[1]);

        // 5. Remplacer une partie de la chaîne
        String maskedData = trimmedData.replace("12345", "*****");
        System.out.println("Chaîne masquée: " + maskedData);
    }
}

Exécutez le code et vérifiez si vos prédictions étaient correctes. N'hésitez pas à modifier le code pour tester d'autres méthodes comme toUpperCase(), startsWith(), etc.


Conclusion

Aujourd'hui, vous avez acquis des compétences fondamentales pour la manipulation de texte en Java.

Points clés à retenir :

  • La classe String est un type référence immuable. Toute "modification" crée un nouvel objet.
  • Pour comparer le contenu des chaînes, utilisez toujours .equals(), et non l'opérateur ==.
  • Le String Pool est un mécanisme d'optimisation pour les chaînes littérales.
  • Vous disposez d'un large éventail de méthodes (substring, replace, split, trim, etc.) pour analyser et transformer des chaînes.

Dans la prochaine leçon, nous allons commencer à explorer les structures de données en Java. Nous débuterons avec les tableaux, qui sont la structure la plus fondamentale pour stocker des collections d'éléments. Vous avez d'ailleurs déjà eu un aperçu de leur utilité avec la méthode split(), qui retourne un tableau de chaînes (String[])