Je ne pouvais le faire qu'avec String, par exemple:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
Existe-t-il un moyen de réaliser cela avec StringBuilder? Merci.
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0, Integer.toString(i));
}
Attention: Il va à l'encontre du but de StringBuilder
, mais il fait ce que vous avez demandé.
Meilleure technique (bien que pas encore idéal):
StringBuilder
.StringBuilder
lorsque vous avez terminé.Cela transformera une solution O ( n ²) en O ( n ).
vous pouvez utiliser strbuilder.insert(0,i);
Peut-être qu'il me manque quelque chose mais vous voulez vous retrouver avec une chaîne qui ressemble à ceci, "999897969594...543210"
, correct?
StringBuilder sb = new StringBuilder();
for(int i=99;i>=0;i--){
sb.append(String.valueOf(i));
}
Comme solution alternative, vous pouvez utiliser une structure LIFO (comme une pile) pour stocker toutes les chaînes. Lorsque vous avez terminé, il suffit de toutes les extraire et de les placer dans StringBuilder. Cela inverse naturellement la ordre des éléments (chaînes) placés en elle.
Stack<String> textStack = new Stack<String>();
// Push the strings to the stack
while(!isReadingTextDone()) {
String text = readText();
textStack.Push(text);
}
// pop the strings and add to the text builder
String builder = new StringBuilder();
while (!textStack.empty()) {
builder.append(textStack.pop());
}
// get the final string
String finalText = builder.toString();
Ce fil est assez ancien, mais vous pourriez aussi penser à une solution récursive en passant à StringBuilder. Cela permet d'éviter tout traitement inverse, etc. Il suffit de concevoir votre itération avec une récursion et de décider avec soin d'une condition de sortie.
public class Test {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
doRecursive(sb, 100, 0);
System.out.println(sb.toString());
}
public static void doRecursive(StringBuilder sb, int limit, int index) {
if (index < limit) {
doRecursive(sb, limit, index + 1);
sb.append(Integer.toString(index));
}
}
}
J'avais une exigence similaire quand je suis tombé sur ce post. Je voulais un moyen rapide de construire une chaîne pouvant se développer des deux côtés, par exemple. ajoutez de nouvelles lettres au recto et au verso de façon arbitraire. Je sais que c’est un vieux billet, mais cela m’a inspiré à essayer quelques façons de créer des chaînes et j’ai pensé partager mes découvertes. J'utilise également quelques constructions Java 8, qui auraient pu optimiser la vitesse dans les cas 4 et 5.
https://Gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e642
Le Gist ci-dessus a le code détaillé que tout le monde peut exécuter. J'ai pris peu de moyens de faire pousser des ficelles dans ce domaine; 1) Ajouter à StringBuilder, 2) Insérer avant de StringBuilder comme indiqué par @Mehrdad, 3) Insérer partiellement de l'avant et de la fin de StringBuilder, 4) Utiliser une liste pour ajouter de la fin, 5) Utiliser un Deque à ajouter de l'avant.
// Case 2
StringBuilder build3 = new StringBuilder();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) build3.append(Integer.toString(i)); else build3.insert(0, Integer.toString(i));
});
String build3Out = build3.toString();
//Case 5
Deque<String> deque = new ArrayDeque<>();
IntStream.range(0, MAX_STR)
.sequential()
.forEach(i -> {
if (i%2 == 0) deque.addLast(Integer.toString(i)); else deque.addFirst(Integer.toString(i));
});
String dequeOut = deque.stream().collect(Collectors.joining(""));
Je vais me concentrer sur l'avant uniquement, c'est-à-dire. cas 2 et cas 5. L'implémentation de StringBuilder détermine en interne la croissance du tampon interne, ce qui, mis à part le déplacement de tout le tampon de gauche à droite en cas d'ajout frontal, limite la vitesse. Bien que le temps nécessaire pour insérer directement à l'avant du StringBuilder prenne des valeurs très élevées, comme le montre @Mehrdad, s'il est nécessaire de n'avoir que des chaînes de longueur inférieure à 90k caractères (ce qui est encore beaucoup), l'insertion avant construire une chaîne dans le même temps qu'il faudrait pour créer une chaîne de la même longueur en ajoutant à la fin. Ce que je dis, c’est que la pénalité de temps est vraiment énorme, mais seulement lorsque vous devez construire des cordes vraiment énormes. Vous pouvez utiliser un deque et joindre les chaînes à la fin, comme indiqué dans mon exemple. Mais StringBuilder est un peu plus intuitif à lire et à coder, et la pénalité importerait peu pour les petites chaînes.
En réalité, la performance du cas 2 est beaucoup plus rapide que celle du cas 1, ce que je ne semble pas comprendre. Je suppose que la croissance de la mémoire tampon interne dans StringBuilder serait la même dans le cas d'ajout frontal et d'ajout précédent. J'ai même fixé le minimum au minimum pour éviter tout retard dans la croissance du tas, si cela avait joué un rôle. Peut-être que quelqu'un qui comprend mieux peut commenter ci-dessous.