Introduction
La manipulation des chaînes de caractères est une compétence essentielle en Java, que ce soit pour résoudre des problèmes algorithmiques ou pour le développement quotidien. Ce guide détaille les opérations courantes sur les chaînes, avec des exemples de code, des cas d'utilisation et des astuces pour éviter les erreurs courantes.
Opérations fondamentales
Création de chaînes
// Méthode 1 : assignation directe (recommandé)
String premierTexte = "Bonjour";
// Méthode 2 : constructeur
String deuxiemeTexte = new String("Bonjour");
Caractéristiques : l'assignation directe réutilise les objets du pool de constantes, tandis que new crée systématiquement un nouvel objet en mémoire.
Obtenir la longueur
int longueur = premierTexte.length(); // 6
Applications : parcours de la chaîne, vérification si elle est vide (longueur 0 pour "").
Accès aux caractères
char caractere = premierTexte.charAt(2); // 'n' (index 2)
Exemple classique : vérification d'un palindrome.
public boolean estPalindrome(String chaine) {
int debut = 0, fin = chaine.length() - 1;
while (debut < fin) {
if (chaine.charAt(debut) != chaine.charAt(fin)) {
return false;
}
debut++;
fin--;
}
return true;
}
Manipulations courantes
Extraction de sous-chaînes
// Extraire de l'index 2 à la fin
String sousChaine1 = premierTexte.substring(2); // "njour"
// Extraire de l'index 1 à 3 (gauche inclusif, droit exclusif)
String sousChaine2 = premierTexte.substring(1, 3); // "on"
Utilisations : récupérer l'extension d'un fichier, analyser des formats spécifiques comme les dates.
Concaténation de chaînes
// Méthode 1 : opérateur + (optimisé à la compilation)
String concatene1 = premierTexte + " monde!";
// Méthode 2 : méthode concat
String concatene2 = premierTexte.concat(" monde!");
// Méthode 3 : StringBuilder (performant pour les opérations multiples)
StringBuilder constructeur = new StringBuilder();
constructeur.append(premierTexte).append(" monde!");
String resultatConcat = constructeur.toString();
Performances : privilégier l'opérateur + pour une concaténation unique, mais utiliser StringBuilder dans les boucles pour éviter la création excessive d'objets.
Recherche dans les chaînes
// Trouver un caractère
int indexCaractere = premierTexte.indexOf('o'); // 1
int dernierIndex = premierTexte.lastIndexOf('r'); // 4
// Trouver une sous-chaîne
int indexSousChaine = premierTexte.indexOf("our"); // 2
Valeur de retour : l'index si trouvé, sinon -1.
Remplacement de contenu
// Remplacement simple
String remplace = premierTexte.replace('o', 'O'); // "BOnjOur"
// Remplacement par expression régulière (remplacer les voyelles par *)
String remplaceRegex = premierTexte.replaceAll("[aeiou]", "*"); // "B*nj**r"
Attention : replaceAll utilise des expressions régulières ; les caractères spéciaux doivent être échappés, par exemple replaceAll("\\+", "-").
Techniques avancées
Découpage en segments
// Découper par virgule
String[] segments1 = "a,b,c".split(","); // ["a", "b", "c"]
// Découper par point (échappement nécessaire)
String[] segments2 = "a.b.c".split("\\."); // ["a", "b", "c"]
Applications : traitement de données CSV, analyse de journaux (logs).
Conversions de types
// Chaîne ↔ tableau de caractères
char[] tableauCaracteres = premierTexte.toCharArray();
String chaineDepuisTableau = new String(tableauCaracteres);
// Autres types vers chaîne
String chaineDepuisEntier = String.valueOf(123); // "123"
String chaineViaToString = Integer.toString(456); // "456"
Validation par expressions régulières
// Vérifier si la chaîne est entièrement numérique
boolean estNumerique = "789".matches("\\d+"); // true
// Valider un format d'email
String email = "utilisateur@exemple.fr";
boolean emailValide = email.matches("[a-zA-Z0-9]+@[a-z]+\\.[a-z]{2,3}");
Scénarios : validation de données, vérification de formats standards.
Optimisation des performances
Choix de la structure adaptée
| Contexte | Type recommandé | Raison |
|---|---|---|
| Modifications fréquentes | StringBuilder |
Non synchronisé mais rapide |
| Environnement multi-thread | StringBuffer |
Synchronisé pour la sécurité |
| Opérations en lecture seule | String |
Immuabilité garantit la sécurité |
Exemple d'implémentation efficace
Cas : inverser une chaîne
// Méthode 1 : avec StringBuilder
public String inverserAvecBuilder(String chaine) {
return new StringBuilder(chaine).reverse().toString();
}
// Méthode 2 : avec tableau de caractères
public String inverserAvecTableau(String chaine) {
char[] caracteres = chaine.toCharArray();
int gauche = 0, droite = caracteres.length - 1;
while (gauche < droite) {
char temp = caracteres[gauche];
caracteres[gauche] = caracteres[droite];
caracteres[droite] = temp;
gauche++;
droite--;
}
return new String(caracteres);
}
Points clés à retenir
- Immuabilité : un objet
Stringne peut pas être modifié après sa création ; toute modification produit un nouvel objet. - Comparaison : pour comparer le contenu, utiliser
equals(); l'opérateur==compare les références. - Pièges de performence : éviter l'utilisation de
+en boucle pour la concaténation. - Sélection de l'outil : choisir entre
String,StringBuilderetStringBufferselon le contexte.
Ces techniques de manipulation sont fréquemment appliquées dans des algorithmes tels que l'inversion de chaînes, la recherche de sous-chaînes (par exemple avec l'algorithme KMP), ou la validation de parenthésage (en utilisant une pile). Maîtriser ces opérations accélère considérablement la résolution de problèmes sur des plateformes comme LeetCode, par exemple le problème 344 (inversion de chaîne).