JavaRush /Blog Java /Random-FR /Introduction à String, StringBuffer et StringBuilder en J...

Introduction à String, StringBuffer et StringBuilder en Java

Publié dans le groupe Random-FR
Il existe trois classes en Java pour travailler avec des données texte : String , StringBuffer et StringBuilder . Chaque développeur rencontre le premier au tout début de l’apprentissage du langage. Et les deux autres ? Quelles sont leurs différences, et quand est-il préférable d'utiliser l'une ou l'autre classe ? En général, la différence entre eux est faible, mais il vaut mieux tout comprendre en pratique :) Introduction à String, StringBuffer et StringBuilder en Java - 1

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
En général, la classe String ne peut pas avoir d'enfants ( 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 :
  1. 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.

  2. La classe String peut être utilisée dans un environnement multithread sans synchronisation supplémentaire.

  3. 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 Objectet 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 aen fait bré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.
Regardons ce code :
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'est mutableune 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)
Pratique:
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 appendde 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 appendrenvoie 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 position start, se terminantend
  • deleteCharAt(int index)— supprime le caractère à la positionindex
  • insert(int offset, String str)— insère une ligne strà la position offset. La méthode insertest également surchargée et peut prendre différents arguments
  • replace(int start, int end, String str)- remplacera tous les caractères d'une startposition à endl'autre parstr
  • reverse()— inverse l'ordre de tous les caractères
  • substring(int start)- renverra une sous-chaîne commençant à la position start
  • substring(int start, int end)- renverra une sous-chaîne commençant de position starten positionend
Une liste complète des méthodes et des constructeurs se trouve dans la documentation officielle . Comment fonctionnent les méthodes ci-dessus ? Voyons en pratique :
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 :

  1. 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.

  2. 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
Vous pouvez étudier ce sujet plus en détail au deuxième niveau de la quête Java Multithreading dans le cours JavaRush :
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION