StringBuilder vs Chaîne envisage de remplacer
Lors de la concaténation de beaucoup de chaînes, j'ai été recommandé de le faire à l'aide d'un StringBuilder
en tant que tel:
StringBuilder someString = new StringBuilder("abc");
someString.append("def");
someString.append("123");
someString.append("moreStuff");
par opposition à
String someString = "abc";
someString = someString + "def";
someString = someString + "123";
someString = someString + "moreStuff";
qui aurait pour résultat la création d'un certain nombre de Chaînes, par opposition à un.
Maintenant, j'ai besoin de faire quelque chose de similaire, mais au lieu d'utiliser la concaténation j'utilise le replace
méthode de Chaîne de caractères en tant que tel:
String someString = SOME_LARGE_STRING_CONSTANT;
someString = someString.replace("$VARIABLE1", "abc");
someString = someString.replace("$VARIABLE2", "def");
someString = someString.replace("$VARIABLE3", "123");
someString = someString.replace("$VARIABLE4", "moreStuff");
Pour accomplir la même chose en utilisant StringBuilder, je dois le faire, juste pour un remplacement:
someString.replace(someString.indexOf("$VARIABLE1"), someString.indexOf("$VARIABLE1")+10, "abc");
Donc ma question est: "Est-il préférable d'utiliser des chaînes de caractères.remplacer et avoir beaucoup de Cordes supplémentaires créés, ou à utiliser StringBuilder encore, et que vous avez beaucoup de longue haleine, tels que celui ci-dessus?"
- Si est génératrice de problèmes de performance, de les modifier. Si il n'y a plus d'importants changements à effectuer, de les modifier. Si l'entrée est vraiment très grand et très souvent utilisé, changez-le. BTW, le secont approche ne fonctionnera pas puisqu'il suffira de le remplacer une fois, vous devez le mettre sur une boucle while. Jetez un oeil à ma réponse.
Vous devez vous connecter pour publier un commentaire.
Il est vrai que StringBuilder tend à être meilleure que la concaténation ou de la modification des Chaînes manuellement, depuis StringBuilder est mutable, tandis que la Chaîne est immuable et que vous avez besoin pour créer une nouvelle Chaîne pour chaque modification.
Juste à noter, cependant, le compilateur Java va les convertir automatiquement un exemple comme ceci:
en quelque chose comme:
Cela dit, sauf si vous remplacez un tas de Cordes, aller pour celui qui est plus lisible et plus facile à gérer. Donc, si vous pouvez le garder plus propre en ayant une séquence de "remplacer" les appels, aller de l'avant et de le faire sur la méthode StringBuilder. La différence sera négligeable par rapport à l'effort que vous vous sauver de traiter avec la triste tragédie de micro-optimisations.
PS
Pour votre exemple de code (qui, comme OscarRyz souligné, ne fonctionnera pas si vous avez plus d'un
"$VARIABLE1"
danssomeString
, dans ce cas, vous aurez besoin d'utiliser une boucle), vous pourriez mettre en cache le résultat de laindexOf
appel dans:Avec
Pas besoin de chercher la Chaîne de caractères à deux reprises 🙂
builder = new StringBuilder(120);builder.append(a()).append(b()).append(c());
Salut, Si nous savons que la taille finale, disons 120 que la chaîne de sortie va être, wont le code ci-dessus mieux que le code auto-généré dans le processus de compilation. Notez que les méthodes a,b,c ne sont pas de retour statique des chaînes codées en dur, de sorte que le compilateur ne peut pas savoir sur quelle valeur pour initialiser le générateur de avec.Devinez quoi? Si vous êtes en cours d'exécution avec Java 1.5+ la concaténation fonctionne de la même façon avec les littéraux de chaîne
et
Sont les mêmes.
Ainsi, le compilateur a fait le travail pour vous déjà.
Bien sûr, il vaut mieux serait de:
Que pour le second, yeap, c'est préférable, mais devrait pas être difficile, avec la puissance de "rechercher et remplacer" et un peu de regex foo
Par exemple, vous pouvez définir une méthode comme dans cet exemple:
Et votre code ressemble à ceci:
Tout ce que vous avez à faire est de saisir éditeur de texte, un déclencheur de quelque chose comme ce vi de recherche et de remplacement:
Lire: "prendre quelque chose dans la parenthèse et qui ressemble à une chaîne littérale, et de le mettre dans cette autre chaîne".
Et votre code va chercher à partir de ce:
à ceci:
En un rien de temps.
Voici un travail de démonstration:
Je dirais allez utiliser StringBuilder mais simplement écrire un wrapper qui facilite rendre le code plus lisible et donc plus facile à gérer, tout en conservant l'efficacité. =D
De SORTIE:
Maintenant vous pouvez simplement utiliser la nouvelle version qui est un simple liner
"old old dudley"
"old old dudley"
et vous obtiendrez"new old dudley"
Au lieu d'avoir de longues lignes comme ça, vous pouvez simplement écrire une méthode de remplacement de pièces de StringBuilder chaînes, quelque chose le long des lignes de ce:
Peut-être la Classe String utilise en interne
méthode pour trouver l'indice de l'ancienne chaîne et la remplacer par la nouvelle chaîne.
Et aussi StringBuilder n'est pas thread-safe de sorte qu'il s'exécute beaucoup plus rapidement.
Si votre chaîne est vraiment grand et vous êtes inquiet au sujet de la performance, je recommanderais l'écriture d'une classe qui prend votre modèle de texte et une liste de variables, puis lit plus la source de la chaîne caractère par caractère et construit le résultat à l'aide de StringBuilder. Que devrait être la plus efficace à la fois en termes de CPU et de la mémoire. Aussi, si vous êtes la lecture de ce texte du modèle à partir d'un fichier que je n'aurais pas de charge tout en mémoire à l'avant. Processus dans des morceaux comme vous le lire à partir du fichier.
Si vous êtes à la recherche d'un moyen agréable de générer une chaîne qui n'est pas tout à fait aussi efficace que StringBuilder mais plus efficace que d'ajouter des chaînes plus et plus vous pouvez utiliser Chaîne de caractères.format(). Il fonctionne comme sprintf() en C. MessageFormat.format() est une option aussi, mais il utilise StringBuffer.
Il y a une autre question qui se pose ici: L'insertion d'une Java chaîne dans une autre chaîne sans concaténation?
Tous les types de codes d'avoir un bug .essayez
yourReplace("x","xy")
.Il boucle infinimentConfiture de Hong-à juste titre - les solutions ci-dessus contiennent tous le potentiel pour faire une boucle à l'infini. Je suppose que la leçon à emporter ici est que les micro-optimisations peuvent souvent causer toutes sortes d'horribles problèmes et ne pas vraiment vous sauver beaucoup. Toujours, quoi qu'il en soit, voici une solution qui ne sera pas de boucle infinie.
même s'il est vrai que les micro-optimisations peuvent être problématiques, il dépend souvent du contexte, par exemple, si vous remplacez arrive à exécuter à l'intérieur d'une boucle avec 10000 itérations, vos verrez une différence de performances significative de la "inutile" optimisations.
dans la plupart des cas cependant, il est préférable de pécher par excès de lisibilité