Différence de mutabilité:
String
est immuable , si vous essayez de modifier leurs valeurs, un autre objet est créé, tandis que StringBuffer
et StringBuilder
sont mutables afin qu'elles puissent changer leurs valeurs.
Différence de sécurité de fil:
La différence entre StringBuffer
et StringBuilder
est que StringBuffer
c'est thread-safe. Ainsi, lorsque l'application doit être exécutée uniquement dans un seul thread, il est préférable de l'utiliser StringBuilder
. StringBuilder
est plus efficace que StringBuffer
.
Situations:
- Si votre chaîne ne change pas, utilisez une classe String car un
String
objet est immuable.
- Si votre chaîne peut changer (exemple: beaucoup de logique et d'opérations dans la construction de la chaîne) et ne sera accessible qu'à partir d'un seul thread, utiliser un
StringBuilder
est suffisant.
- Si votre chaîne peut changer et sera accessible à partir de plusieurs threads, utilisez un
StringBuffer
car StringBuffer
est synchrone afin que vous ayez la sécurité des threads.
Strings
lorsque nous modifions la valeur, un autre objet est créé. L'ancienne référence d'objet est-elle annulée afin qu'elle puisse être récupérée par leGC
ou est-elle même récupérée?String
avecStringBuilder
?String
lorsqu'une structure immuable est appropriée; l'obtention d'une nouvelle séquence de caractères à partir d'unString
peut entraîner une pénalité de performance inacceptable, que ce soit en temps CPU ou en mémoire (l'obtention de sous-chaînes est efficace CPU car les données ne sont pas copiées, mais cela signifie qu'une quantité potentiellement beaucoup plus importante de données peut rester allouée).StringBuilder
lorsque vous devez créer une séquence de caractères modifiable, généralement pour concaténer plusieurs séquences de caractères ensemble.StringBuffer
dans les mêmes circonstances que vous utiliseriezStringBuilder
, mais lorsque les modifications apportées à la chaîne sous-jacente doivent être synchronisées (car plusieurs threads lisent / modifient le tampon de chaîne).Voir un exemple ici .
la source
Les bases:
String
est une classe immuable, elle ne peut pas être modifiée.StringBuilder
est une classe modifiable qui peut être ajoutée, les caractères remplacés ou supprimés et finalement convertis enString
StringBuffer
est la version synchronisée d'origine deStringBuilder
Vous devriez préférer
StringBuilder
dans tous les cas où vous n'avez qu'un seul thread accéder à votre objet.Les détails:
Notez également que ce
StringBuilder/Buffers
n'est pas magique, ils utilisent simplement un tableau comme objet de support et que le tableau doit être réalloué chaque fois qu'il est plein. Soyez sûr et créez vosStringBuilder/Buffer
objets assez grands à l'origine où ils n'ont pas besoin d'être constamment redimensionnés à chaque.append()
appel.Le redimensionnement peut devenir très dégénéré. Il redimensionne fondamentalement le tableau de sauvegarde à 2 fois sa taille actuelle chaque fois qu'il doit être étendu. Cela peut entraîner l'allocation de grandes quantités de RAM et leur non-utilisation lorsque les
StringBuilder/Buffer
classes commencent à grossir.En Java
String x = "A" + "B";
utilise unStringBuilder
dans les coulisses. Donc, pour les cas simples, il n'y a aucun avantage à déclarer le vôtre. Mais si vous construisez desString
objets qui sont grands, disons moins de 4k, alors déclarerStringBuilder sb = StringBuilder(4096);
est beaucoup plus efficace que la concaténation ou utiliser le constructeur par défaut qui n'est que de 16 caractères. Si votreString
va être inférieur à 10k, initialisez-le avec le constructeur à 10k pour être sûr. Mais s'il est initialisé à 10k alors vous écrivez 1 caractère de plus que 10k, il sera réalloué et copié dans un tableau de 20k. Il est donc préférable d'initialiser haut que bas.Dans le cas du redimensionnement automatique, au 17e caractère, le tableau de sauvegarde est réalloué et copié sur 32 caractères, au 33e caractère, cela se produit à nouveau et vous pouvez réallouer et copier le tableau en 64 caractères. Vous pouvez voir comment cela dégénère en beaucoup de réallocations et de copies, ce que vous essayez vraiment d'éviter d'utiliser
StringBuilder/Buffer
en premier lieu.Ceci provient du code source JDK 6 pour AbstractStringBuilder
Une meilleure pratique consiste à initialiser
StringBuilder/Buffer
un peu plus grand que vous pensez que vous aurez besoin si vous ne savez pas tout de suite quelleString
sera la taille mais vous pouvez le deviner. Une allocation de mémoire légèrement supérieure à celle dont vous avez besoin sera meilleure que de nombreuses réallocations et copies.Méfiez-vous également d'initialiser un
StringBuilder/Buffer
avec unString
car cela n'allouera que la taille de la chaîne + 16 caractères, ce qui dans la plupart des cas ne fera que démarrer le cycle de réallocation et de copie dégénéré que vous essayez d'éviter. Ce qui suit est directement issu du code source Java 6.Si, par hasard, vous vous retrouvez avec une instance
StringBuilder/Buffer
que vous n'avez pas créée et que vous ne pouvez pas contrôler le constructeur appelé, il existe un moyen d'éviter le comportement dégénéré de réallocation et de copie. Appelez.ensureCapacity()
avec la taille que vous souhaitez pour vous assurer que votre résultatString
s'intégrera.Les alternatives:
Tout comme une note, si vous faites de la
String
construction et de la manipulation très lourdes , il existe une alternative beaucoup plus axée sur les performances appelée Cordes .Une autre alternative consiste à créer une
StringList
implémentation en sous-classantArrayList<String>
et en ajoutant des compteurs pour suivre le nombre de caractères sur chaque.append()
opération de mutation de la liste, puis remplacer.toString()
pour créer uneStringBuilder
taille exacte dont vous avez besoin et parcourir la liste et construire la sortie, vous pouvez même en faireStringBuilder
une variable d'instance et «mettre en cache» les résultats.toString()
et ne devez la régénérer que lorsque quelque chose change.N'oubliez pas non plus de
String.format()
créer une sortie au format fixe, qui peut être optimisée par le compilateur au fur et à mesure qu'elle l'améliore.la source
String x = "A" + "B";
vraiment pour être un StringBuilder? Pourquoi ne compilerait-il pas simplementString x = "AB";
, il ne devrait utiliser un StringBuilder que si les composants ne sont pas connus au moment de la compilation.Voulez-vous dire, pour la concaténation?
Exemple réel: vous souhaitez créer une nouvelle chaîne à partir de nombreuses autres .
Par exemple pour envoyer un message:
Chaîne
StringBuilder
Ou
StringBuffer (la syntaxe est exactement comme avec StringBuilder, les effets diffèrent)
À propos
StringBuffer
contre.StringBuilder
Le premier est synchronisé et plus tard ne l'est pas.
Donc, si vous l'invoquez plusieurs fois dans un seul thread (ce qui représente 90% des cas),
StringBuilder
il s'exécutera beaucoup plus rapidement car il ne s'arrêtera pas pour voir s'il possède le verrou de thread.Donc, il est recommandé de l'utiliser
StringBuilder
(à moins bien sûr que vous ayez plus d'un thread y accédant en même temps, ce qui est rare)String
la concaténation (en utilisant l'opérateur + ) peut être optimisée par le compilateur pour l'utiliser enStringBuilder
dessous, donc, ce n'est plus quelque chose à craindre, dans les jours les plus anciens de Java, c'était quelque chose que tout le monde devrait éviter à tout prix, car chaque concaténation créé un nouvel objet String. Les compilateurs modernes ne le font plus, mais c'est toujours une bonne pratique à utiliser à laStringBuilder
place au cas où vous utilisez un "ancien" compilateur.Éditer
Juste pour qui est curieux, voici ce que le compilateur fait pour cette classe:
javap -c StringConcatenation
Les lignes numérotées de 5 à 27 correspondent à la chaîne nommée "littéral"
Les lignes numérotées 31-53 correspondent à la chaîne nommée "builder"
Il n'y a aucune différence, exactement le même code est exécuté pour les deux chaînes.
la source
StringBuilder
concaténation de chaîne à faire sur le côté droit de l'affectation. Toute bonne implémentation utilisera un StringBuilder dans les coulisses comme vous le dites. De plus, votre exemple"a" + "b"
serait compilé en un seul littéral,"ab"
mais si vous l'utilisiez,StringBuilder
il en résulterait deux appels inutiles àappend()
."a"+"b"
mais pour dire ce qu'était une concaténation de chaînes, je la change pour être explicite. Ce que vous ne dites pas, c'est pourquoi ce n'est pas une bonne pratique de le faire. C'est exactement ce que fait un compilateur (moderne). @ flou, je suis d'accord, surtout quand vous savez quelle serait la taille de la chaîne finale (aprox).la source
synchronised
et c'est pourquoi .Chaîne
Le
String class
représente des chaînes de caractères. Tous les littéraux de chaîne du programme Java, tels que ceux qui"abc"
sont implémentés en tant qu'instances de cette classe.Les objets chaîne sont immuables une fois qu'ils sont créés, nous ne pouvons pas changer. (Les chaînes sont des constantes )
Si une chaîne est créée en utilisant constructeur ou méthode alors ces chaînes seront stockées dans Heap mémoire ainsi que
SringConstantPool
. Mais avant d'enregistrer dans le pool, il invoque uneintern()
méthode pour vérifier la disponibilité des objets avec le même contenu dans le pool en utilisant la méthode equals. Si la copie de chaîne est disponible dans le pool, renvoie la référence. Sinon, l'objet String est ajouté au pool et renvoie la référence.+
) et pour la conversion d'autres objets en chaînes. La concaténation de chaînes est implémentée via la classe StringBuilder (ou StringBuffer) et sa méthode append.Les littéraux de chaîne sont stockés dans
StringConstantPool
.StringBuilder et StringBuffer sont des séquences de caractères modifiables. Cela signifie que l'on peut changer la valeur de ces objets. StringBuffer a les mêmes méthodes que StringBuilder, mais chaque méthode de StringBuffer est synchronisée, elle est donc thread-safe.
Les données StringBuffer et StringBuilder ne peuvent être créées qu'en utilisant un nouvel opérateur. Ainsi, ils sont stockés dans la mémoire du tas.
Les instances de StringBuilder ne sont pas sûres pour une utilisation par plusieurs threads. Si une telle synchronisation est requise, il est recommandé d'utiliser StringBuffer.
StringBuffer et StringBuilder ont des méthodes spéciales comme.,
replace(int start, int end, String str)
Etreverse()
.Quand utiliser lequel?
Si vous n'allez pas changer la valeur à chaque fois, il vaut mieux utiliser
String Class
. Dans le cadre de Generics si vous souhaitez trierComparable<T>
ou comparer une valeur, optez pourString Class
.Si vous allez modifier la valeur à chaque fois, optez pour StringBuilder qui est plus rapide que StringBuffer. Si plusieurs threads modifient la valeur, optez pour StringBuffer.
la source
En outre,
StringBuffer
est thread-safe, ce quiStringBuilder
n'est pas le cas.Ainsi, dans une situation en temps réel lorsque différents threads y accèdent, cela
StringBuilder
pourrait avoir un résultat non déterministe.la source
Notez que si vous utilisez Java 5 ou une version plus récente, vous devez utiliser à la
StringBuilder
place deStringBuffer
. Dans la documentation de l'API:Dans la pratique, vous n'utiliserez presque jamais cela à partir de plusieurs threads en même temps, donc la synchronisation qui le
StringBuffer
fait est presque toujours inutile.la source
Personnellement, je ne pense pas que le monde réel puisse être utilisé
StringBuffer
. Quand voudrais-je jamais communiquer entre plusieurs threads en manipulant une séquence de caractères? Cela ne semble pas du tout utile, mais je n'ai peut-être pas encore vu la lumière :)la source
La différence entre String et les deux autres classes est que String est immuable et les deux autres sont des classes mutables.
Mais pourquoi nous avons deux classes dans le même but?
La raison en est que
StringBuffer
Thread est sûr etStringBuilder
ne l'est pas.StringBuilder
est une nouvelle classeStringBuffer Api
et elle a été introduite dansJDK5
et est toujours recommandée si vous travaillez dans un environnement à thread unique car c'est beaucoupFaster
Pour des détails complets, vous pouvez lire http://www.codingeek.com/java/stringbuilder-and-stringbuffer-a-way-to-create-mutable-strings-in-java/
la source
En java, String est immuable. Étant immuables, nous voulons dire qu'une fois qu'une chaîne est créée, nous ne pouvons pas changer sa valeur. StringBuffer est modifiable. Une fois qu'un objet StringBuffer est créé, nous ajoutons simplement le contenu à la valeur de l'objet au lieu de créer un nouvel objet. StringBuilder est similaire à StringBuffer mais il n'est pas thread-safe. Les méthodes de StingBuilder ne sont pas synchronisées mais par rapport aux autres chaînes, le Stringbuilder s'exécute le plus rapidement. Vous pouvez apprendre la différence entre String, StringBuilder et StringBuffer en les implémentant.
la source