String

String: constante String, la longueur de la chaîne est immuable. En Java, String est immuable.

La classe String contient la définition suivante :

/** The value is used for character storage. */
private final char value[];

/** The offset is the first index of the storage that is used. */
private final int offset;

/** The count is the number of characters in the String. */
private final int count;

Le tableau utilisé pour stocker les caractères est déclaré final, il ne peut donc être affecté qu'une seule fois et ne peut plus être modifié.

StringBuffer(JDK1.0)

StringBuffer: variable String (synchronisée, c'est-à-dire thread-safe). Si vous devez fréquemment modifier le contenu d'une chaîne, pour des raisons d'efficacité, il est préférable d'utiliser StringBuffer. Si vous souhaitez le convertir en type String, vous pouvez appeler la méthode toString() de StringBuffer.

Java.lang.StringBufferUne séquence de caractères mutable et sûre pour les threads. À tout moment, elle contient une séquence de caractères déterminée, mais la longueur et le contenu de la séquence peuvent être modifiés via certains appels de méthode. Les tampons de chaînes peuvent être utilisés en toute sécurité par plusieurs threads.

StringBufferLes principales opérations sur celui-ci sont les méthodes append et insert, qui peuvent être surchargées pour accepter tout type de données. Chaque méthode convertit effectivement les données fournies en une chaîne, puis ajoute ou insère les caractères de cette chaîne dans le tampon de chaîne.

  • La méthode append ajoute toujours ces caractères à la fin du tampon ;
  • la méthode insert ajoute des caractères à l'endroit spécifié.

Par exemple, sizfait référence à un objet tampon de chaîne dont le contenu actuel eststart, alors cet appel de méthodez.append("le")fera en sorte que le tampon de chaîne contiennestartle, etz.insert(4, "le")modifiera le tampon de chaîne de sorte qu'il contiennestarlet 。

StringBuilder(JDK5.0)

StringBuilder: variable String (non sûre pour les threads). En interne, un objet StringBuilder est traité comme un tableau de longueur variable contenant une séquence de caractères.

java.lang.StringBuilder est une séquence de caractères mutable, ajoutée récemment dans JDK 5.0. Cette classe fournit une API compatible avec StringBuffer, mais ne garantit pas la synchronisation. Cette classe est conçue pour être utilisée comme un remplacement simple de StringBuffer, utilisé lorsque le tampon de chaîne est utilisé par un seul thread (cette situation est très courante).

Ses constructeurs sont les suivants :

Constructeur Description
StringBuilder() Crée un objet StringBuilder avec une capacité de 16 (16 éléments vides)
StringBuilder(CharSequence cs) Crée un objet StringBuilder contenant cs, avec 16 éléments vides ajoutés à la fin
StringBuilder(int initCapacity) Crée un objet StringBuilder avec une capacité de initCapacity
StringBuilder(String s) Crée un objet StringBuilder contenant s, avec 16 éléments vides ajoutés à la fin

Dans la plupart des cas,StringBuilder > StringBuffer. Cela s'explique principalement par le fait que le premier n'a pas besoin de prendre en compte la sécurité des threads.

Différences entre les trois

La principale différence de performance entre le type String et StringBuffer : String est un objet immuable, donc chaque fois qu'un type String est modifié, un nouvel objet String est généré, puis le pointeur est dirigé vers le nouvel objet String. Par conséquent, il ne faut pas utiliser String pour les chaînes dont le contenu change fréquemment, car générer un objet à chaque fois affecte les performances du système, en particulier lorsqu'il y a beaucoup d'objets non référencés en mémoire, le GC de la JVM se met à fonctionner et les performances diminuent.

Lors de l'utilisation de la classe StringBuffer, les opérations sont effectuées sur l'objet StringBuffer lui-même à chaque fois, plutôt que de générer de nouveaux objets et de modifier les références d'objets. Par conséquent, dans la plupart des cas, StringBuffer est recommandé, en particulier lorsque les objets String changent fréquemment.

Dans certains cas particuliers, la concaténation de chaînes d'objets String est en fait compilée par le compilateur Java en concaténation d'objets StringBuffer, donc à ces moments-là les objets String ne sont pas plus lents que les objets StringBuffer, par exemple :

String s1 = “This is only a” + “ simple” + “ test”;
StringBuffer Sb = new StringBuilder(“This is only a”).append(“ simple”).append(“ test”);

La vitesse de génération de l'objet String s1 n'est pas plus lente que celle de StringBuffer. En fait, dans le compilateur Java, la conversion suivante est automatiquement effectuée :

Le compilateur Java compile directement la première instruction ci-dessus en :

String s1 = “This is only a simple test”;  

La vitesse est donc très rapide. Mais il faut noter que si les chaînes concaténées proviennent d'autres objets String, le compilateur Java ne les convertira pas automatiquement, et la vitesse ne sera pas aussi rapide, par exemple :

String s2 = “This is only a”;  
String s3 = “ simple”;  
String s4 = “ test”;  
String s1 = s2 + s3 + s4;  

À ce moment-là, le compilateur Java le fera strictement de la manière originale. L'opération de concaténation de String (c'est-à-dire +) est implémentée à l'aide de la méthode append de StringBuilder (ou StringBuffer). À ce moment-là, pour la situation ci-dessus, si s2, s3 et s4 sont définis comme String, un StringBuffer (ou StringBuilder) supplémentaire doit être créé lors de la concaténation, puis le StringBuffer est converti en String. Si StringBuffer (ou StringBuilder) est utilisé, il n'est pas nécessaire de créer un StringBuffer supplémentaire.

Stratégies d'utilisation

  • (1) Principe de base : si vous souhaitez opérer sur une petite quantité de données, utilisez String ; pour une opération monothread sur de grandes quantités de données, utilisez StringBuilder ; pour une opération multithread sur de grandes quantités de données, utilisez StringBuffer.

  • (2) N'utilisez pas le "+" de la classe String pour des concaténations fréquentes, car les performances sont extrêmement mauvaises. Vous devriez utiliser la classe StringBuffer ou StringBuilder. C'est un principe relativement important dans l'optimisation Java. Par exemple :

    String result = "";
    for (String s : hugeArray) {
        result = result + s;
    }
    
    // 使用StringBuilder
    StringBuilder sb = new StringBuilder();
    for (String s : hugeArray) {
        sb.append(s);
    }
    String result = sb.toString();
    

    Lorsque la situation ci-dessus se produit, nous devrions évidemment utiliser la deuxième méthode, car dans la première méthode, chaque boucle vacréer un résultat String pour sauvegarder le résultat. À part cela, les deux sont essentiellement identiques (pourJDK 1.5 et versions ultérieures)。

  • (3) Afin d'obtenir de meilleures performances, vous devriez spécifier leur capacité autant que possible lors de la construction de StringBuffer ou StringBuilder. Bien sûr, si la longueur de la chaîne sur laquelle vous opérez ne dépasse pas 16 caractères, vous n'avez pas besoin de la spécifier. Lorsque la capacité n'est pas spécifiée, un objet d'une capacité de 16 est construit par défaut. Ne pas spécifier la capacité réduira considérablement les performances.

  • (4) StringBuilder est généralement utilisé à l'intérieur des méthodes pour réaliser des fonctions similaires+. Comme il n'est pas thread-safe, il peut être abandonné après usage. StringBuffer est principalement utilisé dans les variables globales.

  • (5) Dans les mêmes conditions, l'utilisation de StringBuilder par rapport à l'utilisation de StringBuffer ne permet d'obtenir qu'une amélioration des performances d'environ 10%~15%, mais elle présente le risque de ne pas être thread-safe. Dans la programmation modulaire réelle, le programmeur responsable d'un certain module peut ne pas être en mesure de déterminer clairement si le module s'exécutera dans un environnement multithread. Par conséquent : à moins que vous ne soyez sûr que le goulot d'étranglement du système se situe sur StringBuffer, et que vous soyez sûr que votre module ne s'exécutera pas en mode multithread, vous pouvez utiliser StringBuilder ; sinon, utilisez quand même StringBuffer.

Source de l'article : https://blog.csdn.net/kingzone_2008/article/details/9220691