Classe de chaîne
Cette classe représente une séquence de caractères. Tous les littéraux de chaîne définis dans les programmes, tels que « This is String » sont des instances de la classe String. String a deux fonctionnalités fondamentales :- c'est une classe immuable
- c'est le dernier cours
final
) et les instances de la classe ne peuvent pas être modifiées après la création ( immutable
). Cela confère à la classe String plusieurs avantages importants :
-
En raison de l'immuabilité, le hashcode d'une instance de la classe String est mis en cache. Il n'est pas nécessaire de l'évaluer à chaque fois car les valeurs des champs de l'objet ne changeront jamais après sa création. Cela donne des performances élevées lors de l'utilisation de cette classe comme clé pour
HashMap
. -
La classe String peut être utilisée dans un environnement multithread sans synchronisation supplémentaire.
-
Une autre fonctionnalité de la classe String est qu'elle surcharge l'
+
opérateur " " en Java. Par conséquent, la concaténation (addition) de chaînes est assez simple :
public static void main(String[] args) {
String command = "Follow" + " " + "the" + " " + "white" + " " + "rabbit";
System.out.println(command); // Follow the white rabbit
}
Sous le capot, la concaténation des chaînes est effectuée par la classe StringBuilder ou StringBuffer (à la discrétion du compilateur) et une méthode append
(nous parlerons de ces classes un peu plus tard). Si l'on ajoute des instances de la classe String avec des instances d'autres classes, ces dernières seront réduites à une représentation sous forme de chaîne :
public static void main(String[] args) {
Boolean b = Boolean.TRUE;
String result = "b is " + b;
System.out.println(result); //b is true
}
C'est une autre propriété intéressante de la classe String : les objets de n'importe quelle classe peuvent être convertis en une représentation sous forme de chaîne en utilisant la méthode toString()
définie dans la classe Object
et héritée par toutes les autres classes. Souvent, la méthode toString() sur un objet est appelée implicitement. Par exemple, lorsque nous affichons quelque chose à l’écran ou ajoutons une chaîne à un objet d’une autre classe. La classe String a une fonctionnalité supplémentaire. Tous les littéraux de chaîne définis dans le code Java, tels que "asdf", sont mis en cache au moment de la compilation et ajoutés au pool de chaînes. Si on exécute le code suivant :
String a = "Wake up, Neo";
String b = "Wake up, Neo";
System.out.println(a == b);
Nous verrons vrai dans la console car les variables feront a
en fait b
référence à la même instance de la classe String qui a été ajoutée au pool de chaînes au moment de la compilation. Autrement dit, différentes instances de la classe avec la même valeur ne sont pas créées et la mémoire est sauvegardée.
Défauts:
Il n'est pas difficile de deviner que la classe String est principalement nécessaire pour travailler avec des chaînes. Mais dans certains cas, les fonctionnalités ci-dessus de la classe String peuvent passer d’avantages à des inconvénients. Une fois les chaînes créées dans le code Java, de nombreuses opérations sont souvent effectuées sur celles-ci :- convertir des chaînes en différents registres ;
- extraction de sous-chaînes ;
- enchaînement;
- etc.
public static void main(String[] args) {
String s = " Wake up, Neo! ";
s = s.toUpperCase();
s = s.trim();
System.out.println("\"" + s + "\"");
}
À première vue, il semble que nous venions de traduire la phrase « Réveille-toi, Neo ! » en majuscules, supprimé les espaces supplémentaires de cette chaîne et l'a mis entre guillemets. En fait, en raison de l'immuabilité de la classe String, à la suite de chaque opération, de nouvelles instances de chaîne sont créées et les anciennes sont supprimées, générant une grande quantité de déchets. Comment éviter le gaspillage de mémoire ?
Classe StringBuffer
Pour gérer la création de déchets temporaires en raison de modifications apportées à un objet String, vous pouvez utiliser la classe StringBuffer. C'estmutable
une classe, c'est-à-dire changeable. Un objet de la classe StringBuffer peut contenir un ensemble spécifique de caractères dont la longueur et la valeur peuvent être modifiées en appelant certaines méthodes. Voyons comment fonctionne cette classe. Pour créer un nouvel objet, utilisez l'un de ses constructeurs, par exemple :
- StringBuffer() - créera un objet vide (sans caractères)
- StringBuffer(String str) - créera un objet basé sur la variable str (contenant tous les caractères de str dans la même séquence)
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer("Not empty");
La concaténation de chaînes via StringBuffer en Java se fait à l'aide du append
. En général, la méthode append
de la classe StringBuffer est surchargée de telle manière qu'elle peut accepter presque tous les types de données :
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append(new Integer(2));
sb.append("; ");
sb.append(false);
sb.append("; ");
sb.append(Arrays.asList(1,2,3));
sb.append("; ");
System.out.println(sb); // 2; false; [1, 2, 3];
}
La méthode append
renvoie l'objet sur lequel elle a été appelée (comme beaucoup d'autres méthodes), ce qui permet de l'appeler en « chaîne ». L'exemple ci-dessus peut s'écrire ainsi :
public static void main(String[] args) {
StringBuffer sb = new StringBuffer();
sb.append(new Integer(2))
.append("; ")
.append(false)
.append("; ")
.append(Arrays.asList(1,2,3))
.append("; ");
System.out.println(sb); // 2; false; [1, 2, 3];
}
La classe StringBuffer dispose d'un certain nombre de méthodes pour travailler avec des chaînes. Listons les principaux :
delete(int start, int end)
— supprime une sous-chaîne de caractères commençant à la positionstart
, se terminantend
deleteCharAt(int index)
— supprime le caractère à la positionindex
insert(int offset, String str)
— insère une lignestr
à la positionoffset
. La méthodeinsert
est également surchargée et peut prendre différents argumentsreplace(int start, int end, String str)
- remplacera tous les caractères d'unestart
position àend
l'autre parstr
reverse()
— inverse l'ordre de tous les caractèressubstring(int start, int end)
- renverra une sous-chaîne commençant de positionstart
en positionend
substring(int start)
- renverra une sous-chaîne commençant à la position
start
public static void main(String[] args) {
String numbers = "0123456789";
StringBuffer sb = new StringBuffer(numbers);
System.out.println(sb.substring(3)); // 3456789
System.out.println(sb.substring(4, 8)); // 4567
System.out.println(sb.replace(3, 5, "ABCDE")); // 012ABCDE56789
sb = new StringBuffer(numbers);
System.out.println(sb.reverse()); // 9876543210
sb.reverse(); // Return the original order
sb = new StringBuffer(numbers);
System.out.println(sb.delete(5, 9)); // 012349
System.out.println(sb.deleteCharAt(1)); // 02349
System.out.println(sb.insert(1, "One")); // 0One2349
}
Avantages :
-
Comme déjà mentionné, StringBuffer est une classe mutable, donc travailler avec elle ne crée pas la même quantité de mémoire inutile qu'avec String. Par conséquent, si de nombreuses modifications sont apportées aux chaînes, il est préférable d'utiliser
StringBuffer
. -
StringBuffer est une classe thread-safe. Ses méthodes sont synchronisées et les instances peuvent être utilisées par plusieurs threads simultanément.
Défauts:
D'une part, la sécurité des threads est un avantage de la classe et, d'autre part, un inconvénient. Les méthodes synchronisées sont plus lentes que les méthodes non synchronisées. C'est là que StringBuilder entre en jeu. Voyons de quel type de classe Java il s'agit - StringBuilder, de quelles méthodes elle dispose et quelles sont ses fonctionnalités.Classe StringBuilder
StringBuilder en Java est une classe qui représente une séquence de caractères. Il est très similaire à StringBuffer en tous points, à l'exception de la sécurité des threads. StringBuilder fournit une API similaire à celle de StringBuffer. Montrons cela à l'aide d'un exemple déjà familier, en remplaçant la déclaration des variables de StringBufer par StringBuilder :public static void main(String[] args) {
String numbers = "0123456789";
StringBuilder sb = new StringBuilder(numbers);
System.out.println(sb.substring(3)); //3456789
System.out.println(sb.substring(4, 8)); //4567
System.out.println(sb.replace(3, 5, "ABCDE")); //012ABCDE56789
sb = new StringBuilder(numbers);
System.out.println(sb.reverse()); //9876543210
sb.reverse(); // Return the original order
sb = new StringBuilder(numbers);
System.out.println(sb.delete(5, 9)); //012349
System.out.println(sb.deleteCharAt(1)); //02349
System.out.println(sb.insert(1, "One")); //0One2349
}
La seule différence est que StringBuffer est thread-safe et que toutes ses méthodes sont synchronisées, contrairement à StringBuilder. C'est la seule fonctionnalité. StringBuilder en Java est plus rapide que StringBuffer en raison de la non-synchronisation des méthodes. Par conséquent, dans la plupart des cas, sauf dans un environnement multithread, il est préférable d'utiliser StringBuilder pour un programme Java. Nous résumons le tout dans un tableau comparatif des trois classes :
Chaîne contre StringBuffer contre StringBuilder
Chaîne | StringBuffer | Générateur de chaînes | |
---|---|---|---|
Changeabilité | Immutable (Non) |
mutable (Oui) |
mutable (Oui) |
Extensibilité | final (Non) |
final (Non) |
final (Non) |
Sécurité du fil | Oui, en raison de l'immuabilité | Oui, à cause de la synchronisation | Non |
Quand utiliser | Lorsque vous travaillez avec des chaînes qui seront rarement modifiées | Lorsque vous travaillez avec des chaînes qui seront fréquemment modifiées dans un environnement multithread | Lorsque vous travaillez avec des chaînes qui seront fréquemment modifiées dans un environnement monothread |
GO TO FULL VERSION