Comment Java faire la concaténation de chaîne à l'aide de “+”?
J'ai lu sur la façon dont Java fonctionne avec +=
de l'opérateur, à l'aide de StringBuilder
.
Est-ce la même chose avec un ("a" + "b")
opération?
Je vous recommande de regarder ce excellent article.
OriginalL'auteur Tom Brito | 2010-04-27
Vous devez vous connecter pour publier un commentaire.
En Java, des instances de Chaîne sont immuables.
Donc, si vous n':
Vous êtes à la création de nouvelles Chaînes de caractères à chaque fois que vous les concaténer.
D'autre part, StringBuilder est comme un tampon, qui peut se développer comme il se doit lors de l'ajout de nouvelles Chaînes.
La règle du pouce est (changé grâce aux commentaires que j'ai eu):
Si vous allez à concaténer beaucoup (c'est à dire, concaténer à l'intérieur d'une boucle, ou de générer un grand XML formé par plusieurs chaîne de variables concaténées), n'utiliser StringBuilder. Sinon, simple concaténation (en utilisant l'opérateur+) sera très bien.
Les optimisations du compilateur également jouer un rôle important lors de la compilation de ce genre de code.
Voiciplus d'explications sur le sujet.Et plus StackOVerflow questions sur la question:
Est-il préférable de réutiliser un StringBuilder dans une boucle?
Quelle est la meilleure façon de construire une chaîne délimitée par des éléments en Java?
StringBuilder vs concaténation de Chaîne dans toString() en Java
Pas nécessairement. Le compilateur d'optimiser toute façon. Changer votre règle de base: "si vous allez utiliser
stringA += stringB
, puis utilisezStringBuilder
au lieu de cela, parce qu'il serait, en effet, manger des tas. Votre réponse est plus ce qui implique que vous avez besoin d'unStringBuilder
pour chaquestringA + stringB
, ce n'est pas vrai.En fait, il est requis par la JLS la concaténation de compiler les constantes de temps des résultats dans un interné
String
. Règle de base devrait être que si vous allez créer unString
dans une boucle et il y a la moindre chance qu'il boucle un certain nombre de fois, l'utilisation d'unStringBuilder
. Inutile de compliquer linéaire concaténation du code avecStirngBuilder
.Non seulement les littéraux de Chaîne concaténée avec + changée pour une seule chaîne au moment de la compilation (dans votre exemple, le compilateur pourrait simplifier en String c = "ab";), le compilateur peut également optimiser la concaténation avec + d'utiliser un StringBuilder de toute façon. Vous ne devriez vraiment besoin d'utiliser StringBuilder pour les plus complexes en ajoutant, comme lors de l'ajout dans une boucle.
D'accord. Avec vous tous. Juste essayé de garder les choses simples. Je pense que les questions demande générale d'une manière générale, la réponse, une réponse, y compris les cas où "a" + "b" peut également être strA + ampb.
OriginalL'auteur Pablo Santa Cruz
Si vous combinez littérale cordes (littéralement
"foo" + "bar"
), le compilateur le fait, au moment de la compilation, et non pas au moment de l'exécution.Si vous avez deux non-chaînes littérales et se joindre à eux avec
+
, le compilateur (du Soleil, de toute façon) utilisera uneStringBuilder
sous les couvertures, mais pas forcément de la manière la plus efficace. Ainsi, par exemple, si vous avez ceci:...ce que le Soleil compilateur va produire effectivement, comme le bytecode semble quelque chose comme ceci:
(Oui, vraiment — voir le démontage à la fin de cette réponse.) Notez qu'il créé un nouveau
StringBuilder
à chaque itération, et ensuite converti le résultat deString
. Ceci est inefficace (mais il n'a pas d'importance, sauf si vous êtes en train de faire un beaucoup) en raison de toute temporaire, les allocations de mémoire: Il alloue unStringBuilder
tampon et, très probablement, de réallouer la mémoire tampon sur le premierappend
[sirv
est à plus de 16 caractères, ce qui est la taille par défaut du tampon] et si ce n'est le premier, puis presque certainement sur la deuxièmeappend
, puis alloue unString
à la fin — et alors il ne tout nouveau sur la prochaine itération.Vous pourriez gagner en efficacité, si nécessaire, par la réécriture à utiliser explicitement un
StringBuilder
:Là, nous avons utilisé un explicite
StringBuilder
et aussi sa première capacité de la mémoire tampon pour être assez grand pour contenir le résultat. C'est plus efficace de la mémoire, mais bien sûr, légèrement moins clair pour les inexpérimentés code mainteneurs et un peu plus d'une douleur à écrire. Donc si vous trouvez un problème de performance avec un serré chaîne concat boucle, cela pourrait être une façon de l'aborder.Vous pouvez le voir, cette sous-le-couvre
StringBuilder
dans l'action avec les éléments suivants de la classe de test:...qui démonte (à l'aide de
javap -c SBTest
) comme ceci:Note de la façon dont une nouvelle
StringBuilder
est créé sur chaque itération de la boucle ainsi créée à l'aide de la capacité de la mémoire tampon par défaut.Tous de cette allocation temporaire des trucs sons laid, mais encore une fois, seulement si vous avez affaire à de substantielles des boucles et/ou des chaînes. Aussi, lorsque la bytecode est exécuté, la JVM peut bien optimiser un peu plus. Sun JVM HotSpot, par exemple, est une très mature JIT optimisation du compilateur. Une fois qu'il est identifié dans la boucle un endroit chaud, il peut bien trouver un moyen de refactoriser le code. Ou pas, bien sûr. 🙂
Ma règle d'or est-je m'inquiéter quand je vois un problème de performance, ou si je sais que je suis en train de faire un beaucoup de concaténation et c'est très probable être un problème de performance et le code ne seront pas affectés de manière significative à partir d'un maintenabilité point de vue si j'utilise un
StringBuilder
à la place. Les enragés anti-prématuré-optimisation de la ligue serait probablement pas d'accord avec moi sur le deuxième. 🙂Brito: en Fait, basé sur la question, je ne suis pas sûr de savoir si un mot, la réponse devrait être "oui" ou "non", alors j'ai pris cela et juste expliqué ce qui se passe. 🙂
super explication! merci
you rock!!(Je sais que ce n'est pas un recommandé de commentaire... j'ai pas pu résister :P)
OriginalL'auteur T.J. Crowder
Oui, c'est la même, mais le compilateur peut en outre d'optimiser les concaténations de littéraux avant la publication du code, donc
"a"+"b"
peut être publié, comme"ab"
directement.En fait, il en débite stupide ordures précisément parce qu'il ne fait pas de distinction entre littérale de concaténation et de non-littérale concat.
OriginalL'auteur Donal Fellows
Pour la concaténation d'un nombre fixe de chaînes dans une expression avec
+
, le compilateur va produire du code à l'aide d'un seulStringBuilder
.E. g. la ligne
résultats dans le même bytecode comme la ligne
lors de la compilation en utilisant le compilateur javac. (L'Éclipse compilateur produit un peu plus de code optimisé en invoquant
new StringBuilder(a)
, et ainsi de gagner un appel de méthode.)Comme mentionné dans d'autres réponses, le compilateur va concaténer des chaînes de caractères littérales comme
"a" + "b"
en une seule chaîne elle-même, la production de pseudo-code binaire qui contient"ab"
à la place.Comme mentionné partout sur le net, vous ne devez pas utiliser
+
de construire une chaîne de au sein d'une boucle, parce que vous copiez le début de la chaîne à des chaînes de caractères. Dans cette situation, vous devez utiliser unStringBuilder
qui vous déclarer en dehors de la boucle.OriginalL'auteur Christian Semrau
Bien lisible, facile à format et de droite vers l'avant, la concaténation de chaînes de caractères avec des "+" est considéré comme mauvais en Java.
Chaque fois que vous ajoutez quelque chose par l'intermédiaire du '+' (Chaîne de caractères.concat()) une nouvelle Chaîne est créé, la vieille Chaîne de contenu est copié, le nouveau contenu est ajouté, et la vieille Chaîne est supprimée. Plus la Chaîne est plus il faut de temps - il n'y a plus de copie et plus de déchets est produite.
Remarque: si vous êtes juste de la concaténation d'un peu (disons 3,4) les chaînes de caractères et non de la construction d'une chaîne par l'intermédiaire d'une boucle ou l'écriture d'une application de test, vous pouvez toujours coller avec "+"
Lors de l'exécution d'une vaste manipulation de chaînes (ou en ajoutant à travers une boucle), en remplaçant "+" avec
StringBuilder
.append est probablement recommandé. Les objets intermédiaires mentionnés dans le cas de la "+" ne sont pas créés lorsappend()
appel de méthode.Également à noter que des optimisations dans le Soleil compilateur Java, ce qui crée automatiquement
StringBuilders
(StringBuffers
< 5.0) quand il voit des concaténations de Chaîne. Mais ce n'est que le Soleil compilateur Java.OriginalL'auteur ring bearer
Source
StringBuilder
sous le couvre.)OriginalL'auteur inkedmn