Quelle est la différence entre String et StringBuffer en Java?

Quelle est la différence entre String et StringBuffer en Java?

y a-t-il une taille maximale pour les ficelles?

63
demandé sur Jonik 2010-03-13 20:25:47

15 réponses

String est utilisé pour manipuler des chaînes de caractères qui ne peuvent pas être changées (en lecture seule et immuable).

StringBuffer est utilisé pour représenter les caractères qui peuvent être modifiés.

en termes de performances, StringBuffer est plus rapide lors de l'exécution de concaténations. C'est parce que lorsque vous concaténez un String , vous créez un nouvel objet (en interne) chaque fois depuis String est immuable.

vous pouvez aussi utiliser StringBuilder qui est semblable à StringBuffer sauf qu'il n'est pas synchronisé. La taille maximale pour l'un ou l'autre de ces Integer.MAX_VALUE (2 31 - 1 = 2,147,483,647) ou la taille maximale de tas divisé par 2 (voir combien de caractères peut avoir une chaîne Java? ). Plus d'informations ici .

75
répondu Vivin Paliath 2017-05-23 11:47:25

A String est immuable, i.e. quand il est créé, il ne peut jamais changer.

A StringBuffer (ou son cousin non synchronisé StringBuilder ) est utilisé lorsque vous avez besoin de construire une corde pièce par pièce sans la performance au-dessus de la construction de lots de petits String s le long du chemin.

la longueur maximale pour les deux est entière.MAX_VALUE, parce qu'ils sont stockés en interne sous forme de tableaux, et les tableaux Java ont seulement un int pour leur longueur pseudo-champ.

l'amélioration de la performance entre String s et StringBuffer s pour la concaténation multiple est assez significative. Si vous exécutez le test code suivant, vous verrez la différence. Sur mon ancien ordinateur portable avec Java 6, je reçois ces résultats:

Concat with String took: 1781ms
Concat with StringBuffer took: 0ms
public class Concat
{
    public static String concatWithString()
    {
        String t = "Cat";
        for (int i=0; i<10000; i++)
        {
            t = t + "Dog";
        }
        return t;
    }
    public static String concatWithStringBuffer()
    {
        StringBuffer sb = new StringBuffer("Cat");
        for (int i=0; i<10000; i++)
        {
            sb.append("Dog");
        }
        return sb.toString();
    }
    public static void main(String[] args)
    {
        long start = System.currentTimeMillis();
        concatWithString();
        System.out.println("Concat with String took: " + (System.currentTimeMillis() - start) + "ms");
        start = System.currentTimeMillis();
        concatWithStringBuffer();
        System.out.println("Concat with StringBuffer took: " + (System.currentTimeMillis() - start) + "ms");
    }
}
34
répondu Simon Nickerson 2010-03-13 17:34:28
String                                          StringBuffer

Immutable                                       Mutable
String s=new String("karthik");                StringBuffer sb=new StringBuffer("karthik")
s.concat("reddy");                             sb.append("reddy");
System.out.println(s);                         System.out.println(sb);
O/P:karthik                                    O/P:karthikreddy

--->once we created a String object            ---->once we created a StringBuffer object
we can't perform any changes in the existing  we can perform any changes in the existing
object.If we are trying to perform any        object.It is nothing but mutablity of 
changes with those changes a new object       of a StrongBuffer object
will be created.It is nothing but Immutability
of a String object

Use String--->If you require immutabilty
Use StringBuffer---->If you require mutable + threadsafety
Use StringBuilder--->If you require mutable + with out threadsafety

String s=new String("karthik");
--->here 2 objects will be created one is heap and the other is in stringconstantpool(scp) and s is always pointing to heap object

String s="karthik"; 
--->In this case only one object will be created in scp and s is always pointing to that object only
22
répondu Karthik Reddy 2013-03-22 06:54:16

String est une classe immuable. Cela signifie qu'une fois que vous instanciez une instance d'une chaîne comme so:

String str1 = "hello";

l'objet en mémoire ne peut pas être modifié. Au lieu de cela, vous devrez créer une nouvelle instance, copier l'ancienne chaîne de caractères et ajouter quoi que ce soit d'autre comme dans cet exemple:

String str1 = "hello";
str1 = str1 + " world!";

ce qui se passe réellement hear est que nous ne mettons pas à jour l'objet str1 existant... nous sommes en train de réattribuer de la mémoire nouvelle, "bonjour" de données et en ajoutant " monde!"à la fin, Paramétrez la référence str1 pour pointer vers cette nouvelle mémoire. Donc, il ressemble vraiment plus à cela sous le capot:

String str1 = "hello";
String str2 = str1 + " world!";
str1 = str2;

il s'ensuit donc que ce processus" copier + coller et déplacer des trucs en mémoire " peut être très coûteux s'il est effectué de façon répétitive.

quand vous êtes dans cette situation d'avoir à faire des choses plus et plus utiliser StringBuilder. Il est mutable et peut ajouter chaînes à la fin de l'actuel car c'est le retour par un nombre croissant] (pas à 100% si c'est la structure de données, pourrait être une liste).

10
répondu Feisty Mango 2011-03-04 17:48:41

De la API:

"151900920 Un" thread-safe, mutable séquence de caractères. Un tampon de chaîne est comme une chaîne, mais peut être modifié. À tout moment, il contient une séquence particulière de caractères, mais la longueur et le contenu de la séquence peuvent être modifiés par certains appels de méthodes.

4
répondu posdef 2011-03-04 16:50:25

un mélangeur de cordes est utilisé pour créer une chaîne simple à partir de plusieurs chaînes, par exemple lorsque vous voulez ajouter des parties d'une chaîne dans une boucle.

vous devez utiliser un StringBuilder à la place d'un StringBuffer lorsque vous n'avez qu'un seul Thread accédant au StringBuffer, puisque le StringBuilder n'est pas synchronisé et donc plus rapide.

AFAIK il n'y a pas de limite supérieure pour la taille des Chaînes en Java comme langue, mais les JVM ont probablement une limite supérieure.

2
répondu Thomas Lötzer 2010-03-13 17:27:03

J'ai trouvé la réponse d'intérêt pour comparer la chaîne de performance vs StringBuffer par Reggie Hutcherso Source : http://www.javaworld.com/javaworld/jw-03-2000/jw-0324-javaperf.html

Java fournit les classes StringBuffer et String, et la classe String est utilisée pour manipuler des chaînes de caractères qui ne peuvent pas être changées. En termes simples, les objets de type String sont lus seulement et immuables. La classe StringBuffer est utilisée pour représenter les caractères qui peuvent être modifiés.

la différence de performance significative entre ces deux classes est que StringBuffer est plus rapide que String lorsqu'il exécute des concaténations simples. Dans le code de manipulation des chaînes de caractères, les chaînes de caractères sont habituellement concaténées. En utilisant la classe String, les concaténations sont généralement effectuées comme suit:

 String str = new String ("Stanford  ");
 str += "Lost!!";

si vous deviez utiliser StringBuffer pour effectuer la même concaténation, vous auriez besoin code qui ressemble à ceci:

 StringBuffer str = new StringBuffer ("Stanford ");
 str.append("Lost!!");
Les développeurs de

supposent généralement que le premier exemple ci-dessus est plus efficace parce qu'ils pensent que le second exemple, qui utilise la méthode d'ajout pour la concaténation, est plus coûteux que le premier exemple, qui utilise l'opérateur + pour concaténer deux objets String.

L'opérateur + semble innocent, mais le code généré produit quelques surprises. L'utilisation d'un batteur à cordes pour la concaténation peut en fait produisez du code qui est significativement plus rapide qu'en utilisant une chaîne de caractères. Pour découvrir pourquoi c'est le cas, nous devons examiner le bytecode généré à partir de nos deux exemples. Le bytecode pour L'exemple utilisant String ressemble à ceci:

0 new #7 <Class java.lang.String>
3 dup 
4 ldc #2 <String "Stanford ">
6 invokespecial #12 <Method java.lang.String(java.lang.String)>
9 astore_1
10 new #8 <Class java.lang.StringBuffer>
13 dup
14 aload_1
15 invokestatic #23 <Method java.lang.String valueOf(java.lang.Object)>
18 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
21 ldc #1 <String "Lost!!">
23 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
26 invokevirtual #22 <Method java.lang.String toString()>
29 astore_1

le bytecode aux emplacements 0 à 9 est exécuté pour la première ligne de code, à savoir:

 String str = new String("Stanford ");

ensuite, le bytecode à l'emplacement 10 à 29 est exécuté pour la concaténation:

 str += "Lost!!";

les Choses deviennent intéressantes ici. Le bytecode généré pour la concaténation crée un objet StringBuffer, puis invoque sa méthode append: l'objet StringBuffer temporaire est créé à l'emplacement 10, et sa méthode append est appelée à l'emplacement 23. Comme la classe String est immuable, un mélangeur de cordes doit être utilisé pour la concaténation.

après la concaténation effectuée sur L'objet StringBuffer, il doit être reconverti en chaîne. C'est fait avec l'appel à la méthode toString à l'emplacement 26. Cette méthode crée un nouvel objet String à partir de L'objet StringBuffer temporaire. La création de cet objet StringBuffer temporaire et sa conversion ultérieure en un objet String sont très chères.

en résumé, les deux lignes de code ci-dessus donnent lieu à la création de trois objets:

  1. Un objet Chaîne de caractères à la position 0
  2. un objet StringBuffer à l'emplacement 10
  3. Un objet de type String au lieu de 26

maintenant, regardons le bytecode généré pour l'exemple en utilisant StringBuffer:

0 new #8 <Class java.lang.StringBuffer>
3 dup
4 ldc #2 <String "Stanford ">
6 invokespecial #13 <Method java.lang.StringBuffer(java.lang.String)>
9 astore_1
10 aload_1 
11 ldc #1 <String "Lost!!">
13 invokevirtual #15 <Method java.lang.StringBuffer append(java.lang.String)>
16 pop

le bytecode aux emplacements 0 à 9 est exécuté pour la première ligne de code:

 StringBuffer str = new StringBuffer("Stanford ");

le bytecode à l'emplacement 10 à 16 est alors exécuté pour la concaténation:

 str.append("Lost!!");

Notez que, comme c'est le cas dans la première exemple, ce code invoque la méthode append d'un objet StringBuffer. Contrairement au premier exemple, cependant, il n'est pas nécessaire de créer un fichier string temporaire et de le convertir en un objet String. Ce code ne crée qu'un seul objet, StringBuffer, à l'emplacement 0.

en conclusion, la concaténation de StringBuffer est significativement plus rapide que la concaténation de String. De toute évidence, les pinces à ficelle devraient être utilisées dans ce type d'opération lorsque cela est possible. Si la fonctionnalité du La classe String est désirée, envisagez d'utiliser un mélangeur de cordes pour la concaténation et ensuite effectuer une conversion en chaîne.

2
répondu NguyenDat 2010-11-23 06:55:49

A StringBuffer ou son frère plus jeune et plus rapide StringBuilder est préférable chaque fois que vous allez faire à beaucoup de chaîne de concaténations dans la saveur de

string += newString;

ou, de manière équivalente

string = string + newString;

parce que les constructions ci-dessus créent implicitement nouvelle chaîne chaque fois qui sera une énorme performance et baisse. Un StringBuffer / StringBuilder est sous le capot mieux pour être comparé à un List<Character> dynamiquement extensible .

1
répondu BalusC 2010-03-13 17:29:49

A String est un tableau de caractères immuable.

a StringBuffer est un tableau de caractères mutables. Souvent converti en String lorsqu'il a muté.

puisque les deux sont un tableau, la taille maximale pour les deux est égale à la taille maximale d'un entier, qui est 2^31-1 (voir JavaDoc , aussi vérifier le JavaDoc pour les deux String et StringBuffer ).C'est parce que l'argument .length d'un tableau est un primitif int . (Voir Tableaux ).

1
répondu Pindatjuh 2010-03-13 17:35:28

chaîne de caractères est immuable, ce qui signifie que lorsque vous effectuez une opération sur une chaîne de caractères, vous créez vraiment une nouvelle chaîne de caractères.

StringBuffer est mutable, et vous pouvez les ajouter ainsi que la réinitialisation sa longueur à 0.

en pratique, le compilateur semble utiliser StringBuffer lors de la concaténation de la chaîne pour des raisons de performance .

1
répondu Matthew Willis 2011-03-04 16:50:41
String is immutable. 

pourquoi? Cochez ici .

StringBuffer is not. It is thread safe. 

D'autres questions comme quand utiliser qui et d'autres concepts peuvent être compris après ce .

Espérons que cette aide.

1
répondu roger_that 2013-07-25 06:44:01

bien que je comprenne que ce n'est pas un facteur de différenciation majeur, j'ai remarqué aujourd'hui que StringBuffer(et StringBuilder) fournit quelques méthodes intéressantes que String ne fournit pas.

  • reverse ()
  • setCharAt ()
1
répondu jaydeep 2014-11-20 03:14:56

en imprimant le hashcode de L'objet String/StringBuffer après toute opération d'ajout également prouver, L'objet String est recréé en interne à chaque fois avec de nouvelles valeurs plutôt que d'utiliser le même objet String.

public class MutableImmutable {

/**
 * @param args
 */
public static void main(String[] args) {
    System.out.println("String is immutable");
    String s = "test";
    System.out.println(s+"::"+s.hashCode());
    for (int i = 0; i < 10; i++) {
        s += "tre";
        System.out.println(s+"::"+s.hashCode());
    }

    System.out.println("String Buffer is mutable");

    StringBuffer strBuf = new StringBuffer("test");
    System.out.println(strBuf+"::"+strBuf.hashCode());
    for (int i = 0; i < 10; i++) {
        strBuf.append("tre");
        System.out.println(strBuf+"::"+strBuf.hashCode());
    }

 }

}

sortie: Il imprime la valeur de l'objet avec son hashcode

    String is immutable
    test::3556498
    testtre::-1422435371
    testtretre::-1624680014
    testtretretre::-855723339
    testtretretretre::2071992018
    testtretretretretre::-555654763
    testtretretretretretre::-706970638
    testtretretretretretretre::1157458037
    testtretretretretretretretre::1835043090
    testtretretretretretretretretre::1425065813
    testtretretretretretretretretretre::-1615970766
    String Buffer is mutable
    test::28117098
    testtre::28117098
    testtretre::28117098
    testtretretre::28117098
    testtretretretre::28117098
    testtretretretretre::28117098
    testtretretretretretre::28117098
    testtretretretretretretre::28117098
    testtretretretretretretretre::28117098
    testtretretretretretretretretre::28117098
    testtretretretretretretretretretre::28117098
1
répondu DeepaGanesh 2016-08-03 17:05:05

les différences sont

  1. Seulement Chaîne classe + opérateur est surchargé. Nous pouvons concater deux objets String en utilisant l'opérateur + , mais dans le cas de StringBuffer nous ne pouvons pas.
  2. Chaîne la classe est primordial toString(), equals(), hashCode() de Objet de la classe, mais StringBuffer remplace uniquement toString().

    String s1 = new String("abc");
    String s2 = new String("abc");
    System.out.println(s1.equals(s2));  // output true
    
    StringBuffer sb1 = new StringBuffer("abc");
    StringBuffer sb2 = new StringBuffer("abc");
    System.out.println(sb1.equals(sb2));  // output false
    
  3. Chaîne la classe est à la fois Serializable ainsi que Comparables , mais StringBuffer est seulement Serializable .

    Set<StringBuffer> set = new TreeSet<StringBuffer>();
    set.add(sb1);
    set.add(sb2);
    System.out.println(set);  // gives ClassCastException because there is no Comparison mechanism
    
  4. nous pouvons créer un objet String avec et sans nouveau opérateur, mais L'objet StringBuffer ne peut être créé qu'en utilisant nouvel opérateur.

  5. String est immuable mais StringBuffer est mutable.
  6. StringBuffer est synchronisé, alors que String ne l'est pas.
  7. StringBuffer est doté d'une méthode reverse() , mais les cordes ne l'ont pas.
1
répondu Arun Sudhakaran 2017-01-18 05:06:43

StringBuffer Performance wise est beaucoup mieux que String ; parce que chaque fois que vous appliquez la concaténation sur un objet String alors un nouvel objet String est créé sur chaque concaténation.

règle principale: les cordes sont immuables (non modifiables) et les cordons sont mutables (modifiables)

Voici l'expérience programmatique où vous obtenez la différence de performance ""

public class Test {

  public static int LOOP_ITERATION= 100000;

  public static void stringTest(){
    long startTime = System.currentTimeMillis();
    String string = "This";
    for(int i=0;i<LOOP_ITERATION;i++){
        string = string+"Yasir";
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);    
  }

  public static void stringBufferTest(){
    long startTime = System.currentTimeMillis();
    StringBuffer stringBuffer = new StringBuffer("This");
    for(int i=0;i<LOOP_ITERATION;i++){
        stringBuffer.append("Yasir");
    }

    long endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime);
  }

  public static void main(String []args){
    stringTest()
    stringBufferTest(); 
  }
 }

Sortie de chaîne sont dans ma machine 14800

sortie de StringBuffer sont dans ma machine 14

0
répondu Yasir Shabbir Choudhary 2016-06-11 10:21:34