12
votes

Les chaînes sont immuables - cela signifie que je ne devrais jamais utiliser + = et seulement Stringbuffer?

Les chaînes sont immuables, signifiant, une fois qu'ils ont été créés, ils ne peuvent pas être changés.

Donc, cela signifie-t-il que cela prendrait plus de mémoire si vous appendez des choses avec + = que si vous avez créé un StringBuffer et que vous avez annexé de texte?

Si vous utilisez + = =, vous créeriez un nouvel "objet" chaque fois que vous devez être enregistré dans la mémoire, n'est-ce pas?


0 commentaires

11 Réponses :


3
votes

Oui. La chaîne est immuable. Pour une utilisation occasionnelle, + = est ok. Si l'opération + = est intensive, vous devez vous tourner vers StressBuilder.


0 commentaires

0
votes

Je pense qu'il s'appuie sur le GC pour collecter la mémoire avec la chaîne abandonnée. Donc, + = avec le constructeur de cordes sera définitivement plus rapide si vous avez beaucoup d'opérations sur la manipulation de chaîne. Mais ce n'est pas un problème pour la plupart des cas.


1 commentaires

Non + = ne serait pas plus rapide lorsque vous faites beaucoup de manipulation de chaîne, Stringbuffer serait beaucoup plus rapide. Vous avez raison sur le GC qui va probablement prendre soin de tous les objets de chaîne abandonnés correctement, mais il reste encore le coût de la création d'objets.



1
votes

exactement. Vous devez utiliser un StringBuilder si si le thread-sécurité n'est pas un problème.

En tant que note latérale: il peut y avoir plusieurs objets de chaîne à l'aide du même support de support [] - par exemple lorsque vous utilisez la sous-chaîne (), aucun nouveau caractère [] ne sera créé, ce qui facilite l'utilisation assez efficace. P>

En outre, les compilateurs peuvent faire une certaine optimisation pour vous. Par exemple, si vous faites p>

static final String FOO = "foo";
static final String BAR = "bar"; 

String getFoobar() {
  return FOO + BAR; // no string concatenation at runtime
}


0 commentaires

0
votes

Oui, vous le feriez et c'est exactement pourquoi vous devez utiliser Stringbuffer pour concaténer beaucoup beaucoup de chaînes.

Notez également que depuis Java 5, vous devez également préférer StringBuilder la plupart du temps. C'est juste une sorte de stringbuffer non synchronisé.


0 commentaires

1
votes

Mais le collecteur des ordures finira par libérer les anciennes chaînes une fois qu'il n'y a pas de références à eux


3 commentaires

Ce n'est pas la poubelle en soi qui est le problème. C'est tout la copie du personnage qui vous tue! Concaténation n par 1 chaînes de caractères utilisant + = copies o (n ^ 2) caractères.


Je ne serais pas si sûr de ça. Certaines cordes se retrouvent dans l'espace de Perm et il n'y a pas de collecteur à ordures pour cette zone autant que je sache. Un objet de chaîne pénètre dans la piscine à l'aide de String.Intern ().


Si vous appelez stagiaire () sur un String qui n'existe que dans une boucle et n'est pas nécessaire en dehors de celui-ci, vous ne devriez pas être codé du tout.



5
votes

en Java 5 ou plus tard, Stringbuffer est le fil sûr, et il y a donc des frais généraux que vous ne devriez pas payer pour moins d'en avoir besoin. StringBuilder a la même API mais n'est pas un fil de sécurité (c'est-à-dire que vous ne devez l'utiliser qu'à un seul fil).

Oui, si vous construisez de grandes chaînes, il est plus efficace d'utiliser StressBuilder. Il ne vaut probablement pas la peine de passer StringBuilder ou Stringbuffer dans le cadre de votre API. C'est trop déroutant.


2 commentaires

Stringbuffer a toujours été synchronisée - ils ne l'ont pas rendue synchronisée pour Java 5, c'est juste pourquoi ils ont introduit StressBuilder.


Cela rend beaucoup plus de sens que ce que j'ai déjà pensé. J'ai remarqué que la documentation passait de 1,4 à 5 et de fil de sécurité est maintenant mentionnée plus en évidence.



25
votes

Oui, vous créerez un nouvel objet à chaque fois avec + =. Cela ne signifie pas que c'est toujours la mauvaise chose à faire, cependant. Cela dépend de la question de savoir si vous souhaitez cette valeur en tant que chaîne, ou si vous allez simplement l'utiliser pour construire la chaîne ultérieure.

Si vous veux le résultat de x + y en tant que chaîne, vous pourriez également simplement utiliser la concaténation de la chaîne. Cependant, si vous allez vraiment (dis) une boucle autour et appendez une autre chaîne, et une autre, etc., n'ayant besoin que du résultat comme une chaîne à la fin, puis Stringbuffer / StringBuilder est la voie à suivre. En effet, la boucle est vraiment où StringBuilder paie sur la concaténation de la chaîne - la différence de performance pour 5 ou même 10 concaténations directes va être assez petite, mais pour des milliers, cela devient beaucoup pire - essentiellement parce que vous obtenez O (n 2 ) Complexité avec la concaténation VS O (n) Complexité avec StressBuilder.

En Java 5 et plus, vous devez utiliser essentiellement StringBuilder - c'est non synchronisé, mais c'est presque toujours bien; Il est très rare de vouloir partager un entre les threads.

J'ai un article sur tout ce que vous pourriez trouver utile.


0 commentaires

7
votes

la règle de base est simple:

Si vous exécutez des concaténations dans une boucle, n'utilisez pas + =

Si vous êtes pas Concaténations en cours d'exécution dans une boucle, en utilisant + = n'a tout simplement pas d'importance. (Sauf si une application critique de performance


0 commentaires

0
votes

Vous avez raison que les chaînes sont immuables, donc si vous essayez de conserver la mémoire tout en faisant beaucoup de concaténation à la chaîne, vous devez utiliser StringBuilder plutôt que + =.

Cependant, cela ne vous dérange peut-être pas. Les programmes sont écrits pour leurs lecteurs humains afin que vous puissiez aller avec clarté. S'il est important que vous optimisez, vous devriez profiler en premier. Sauf si votre programme est très lourdement pondéré pour l'activité des cordes, il y aura probablement d'autres goulots d'étranglement.


0 commentaires

5
votes

Je suis d'accord avec toutes les réponses postées ci-dessus, mais cela vous aidera un peu à comprendre plus sur la mise en œuvre de Java. Le JVM utilise des Stringbuffers en interne pour compiler l'opérateur String + (à partir du Stringbuffer Javadoc ):

Les tampons de cordes sont utilisés par le compilateur à mettre en œuvre le binaire Opérateur de concaténation de chaîne +. Pour Exemple, le code: p>

     x = new StringBuffer().append("a").append(4).append("c")
                           .toString()


0 commentaires

0
votes

non

Il n'utilisera plus de mémoire. Oui, de nouveaux objets sont créés, mais les anciens sont recyclés. En fin de compte, la quantité de mémoire utilisée est la même.


0 commentaires