Solo pude hacer esto con String, por ejemplo:
String str="";
for(int i=0;i<100;i++){
str=i+str;
}
¿Hay alguna forma de lograr esto con StringBuilder? Gracias.
StringBuilder sb = new StringBuilder();
for(int i=0;i<100;i++){
sb.insert(0, Integer.toString(i));
}
Advertencia: frustra el propósito deStringBuilder
, pero hace lo que pediste.
Mejor técnica (aunque todavía no es la ideal):
StringBuilder
.StringBuilder
cuando haya terminado.Esto convertirá una solución de O ( n ²) en O ( n ).
AbstractStringBuilder
mover todos los contenidos más allá del índice de inserción para encontrar espacio para los insertados. Sin embargo, ese es un detalle de implementación, no uno de principio.puedes usar
strbuilder.insert(0,i);
fuente
Tal vez me esté perdiendo algo, pero quieres terminar con un String que se vea así
"999897969594...543210"
, ¿correcto?StringBuilder sb = new StringBuilder(); for(int i=99;i>=0;i--){ sb.append(String.valueOf(i)); }
fuente
Como solución alternativa, puede usar una estructura LIFO (como una pila) para almacenar todas las cadenas y cuando haya terminado, simplemente sáquelas todas y colóquelas en StringBuilder. Naturalmente, invierte el orden de los elementos (cadenas) colocados en él.
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();
fuente
ArrayDeque
debe usarse en lugar deStack
. "La interfaz {@link Deque} y sus implementaciones proporcionan un conjunto más completo y coherente de operaciones de pila LIFO, que deben usarse con preferencia a esta clase"Este hilo es bastante antiguo, pero también podría pensar en una solución recursiva pasando el StringBuilder para completar. Esto permite evitar cualquier procesamiento inverso, etc. Solo necesita diseñar su iteración con una recursividad y decidir cuidadosamente una condición de salida.
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)); } } }
fuente
Tenía un requisito similar cuando me topé con esta publicación. Quería una forma rápida de construir una cadena que pueda crecer desde ambos lados, es decir. agregue nuevas letras en la parte delantera y trasera de forma arbitraria. Sé que esta es una publicación antigua, pero me inspiró a probar algunas formas de crear cadenas y pensé en compartir mis hallazgos. También estoy usando algunas construcciones de Java 8 en esto, que podrían haber optimizado la velocidad en los casos 4 y 5.
https://gist.github.com/SidWagz/e41e836dec65ff24f78afdf8669e6420
La esencia anterior tiene el código detallado que cualquiera puede ejecutar. Tomé algunas formas de hacer crecer las cuerdas en esto; 1) Adjuntar a StringBuilder, 2) Insertar al frente de StringBuilder como se muestra en @Mehrdad, 3) Insertar parcialmente desde el frente y el final del StringBuilder, 4) Usar una lista para agregar desde el final, 5) Usar un Deque para añadir desde el frente.
// 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(""));
Me centraré en los casos adjuntos al frente, es decir. caso 2 y caso 5. La implementación de StringBuilder decide internamente cómo crece el búfer interno, lo que además de mover todo el búfer de izquierda a derecha en caso de adición frontal limita la velocidad. Si bien el tiempo que se tarda en insertar directamente al frente del StringBuilder crece a valores realmente altos, como lo muestra @Mehrdad, si solo se necesita tener cadenas de menos de 90k caracteres (que todavía es mucho), el inserto frontal construya una cadena en el mismo tiempo que se necesitaría para construir una cadena de la misma longitud agregando al final. Lo que estoy diciendo es que la penalización de tiempo de hecho patea y es enorme, pero solo cuando tienes que construir cuerdas realmente enormes. Se podría usar una deque y unir las cuerdas al final como se muestra en mi ejemplo.
En realidad, el rendimiento para el caso 2 es mucho más rápido que el del caso 1, que no parece entender. Supongo que el crecimiento del búfer interno en StringBuilder sería el mismo en el caso de la adición frontal y posterior. Incluso establecí el montón mínimo en una cantidad muy grande para evitar retrasos en el crecimiento del montón, si eso hubiera jugado un papel. Quizás alguien que tenga una mejor comprensión pueda comentar a continuación.
fuente
Difference Between String, StringBuilder And StringBuffer Classes String String is immutable ( once created can not be changed )object. The object created as a String is stored in the Constant String Pool. Every immutable object in Java is thread-safe, which implies String is also thread-safe. String can not be used by two threads simultaneously. String once assigned can not be changed. StringBuffer StringBuffer is mutable means one can change the value of the object. The object created through StringBuffer is stored in the heap. StringBuffer has the same methods as the StringBuilder , but each method in StringBuffer is synchronized that is StringBuffer is thread safe . Due to this, it does not allow two threads to simultaneously access the same method. Each method can be accessed by one thread at a time. But being thread-safe has disadvantages too as the performance of the StringBuffer hits due to thread-safe property. Thus StringBuilder is faster than the StringBuffer when calling the same methods of each class. String Buffer can be converted to the string by using toString() method. StringBuffer demo1 = new StringBuffer("Hello") ; // The above object stored in heap and its value can be changed. / // Above statement is right as it modifies the value which is allowed in the StringBuffer StringBuilder StringBuilder is the same as the StringBuffer, that is it stores the object in heap and it can also be modified. The main difference between the StringBuffer and StringBuilder is that StringBuilder is also not thread-safe. StringBuilder is fast as it is not thread-safe. / // The above object is stored in the heap and its value can be modified / // Above statement is right as it modifies the value which is allowed in the StringBuilder
fuente
Puede utilizar el método de inserción con el desplazamiento. como offset establecido en '0' significa que está agregando al frente de su StringBuilder.
StringBuilder sb = new StringBuilder(); for(int i=0;i<100;i++){ sb.insert(0,i); }
NOTA : como el método de inserción acepta todos los tipos de primitivas, puede usar para int, long, char [], etc.
fuente
Qué tal si:
StringBuilder builder = new StringBuilder(); for(int i=99;i>=0;i--){ builder.append(Integer.toString(i)); } builder.toString();
O
StringBuilder builder = new StringBuilder(); for(int i=0;i<100;i++){ builder.insert(0, Integer.toString(i)); } builder.toString();
Pero con esto, estás haciendo la operación O (N ^ 2) en lugar de O (N).
Fragmento de documentos java:
fuente