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?
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 .
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");
}
}
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
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).
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.
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.
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:
- Un objet Chaîne de caractères à la position 0
- un objet StringBuffer à l'emplacement 10
- 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.
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 .
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 ).
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 .
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.
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 ()
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
les différences sont
- 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.
-
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
-
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
-
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.
- String est immuable mais StringBuffer est mutable.
- StringBuffer est synchronisé, alors que String ne l'est pas.
- StringBuffer est doté d'une méthode reverse() , mais les cordes ne l'ont pas.
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