String Vs StringBuilder

Pues bien hace unos días estaba estudiando como funciona StringBuilder ya que a diferencia de crear una cadena con String, este no crea uno nuevo por cada cambio que se haga si no que trabaja con el que se crea la primer vez, por ejemplo

StringBuilder sb=new StringBuilder("hola");
sb.append(" -");//trabajara sobre el que ya se había creado no crea uno nuevo

A diferencia de crear un String s="Hola";
si yo hago un s=s+"-"; se crea uno nuevo y la referencia del anterior se pierde para apuntar a este nuevo

Mi duda es la siguiente con un String yo puedo aplicarle el metodo replace(char oldChar, char newChar) que remplazaria todos los caracteres que contengan lo que se quiera remplazar por lo nuevo, y en un StringBuilder tengo este replace(int start, int end, String str) que remplzaza el string especificado de una posicion inicial a una posicion final,¿ si yo no conozco las posiciones y solo quisiera remplazar supongamos todas las a por b como podria hacerle?

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

indexOf

Tendrías que encontrar cada b y reemplazarla en el StringBuilder:

 

Vuele el objeto String o remplaza directamente

 

@BT aunque con eso pierdes el

@BT aunque con eso pierdes el beneficio que describe sakura inicialmente, que es el de no tener que crear nuevos objetos, que dependiendo del contexto donde se use puede ser significativo o no. Por ejemplo si solo se usa 1 - 1000 veces, la direrencia de desempeño es imperceptible, pero si se usa intensamente crea una diferencia notable solo para terminar haciendo lo que menciona Enrique.

Por ejemplo, esta es la implementación de replace(char,char) en Apache Harmony ( una implementacion de Java ) ( dar click en el + para ver el código fuente )

Haciendo un micro-BenchMark

El resultado me deja bastante impresionado
En menos de 1000 la solución que usa el for es mas rápida , pero con datos sobre 10000 o 1000000 la solucion simple es muchísimo mas rápida mas la otra solución es realmente lenta.
 

Ya no te entendí ¿cual es

Ya no te entendí ¿cual es cual?

Imagen de ezamudio

Ese for...

Ese for con dos if's... creo que los dos if's sobran (bueno uno sobra realmente). Si usas   en vez de esas comparaciones, el performance mejorará muchísimo. Sobretodo porque estás usando   3 veces en cada iteración, y ese método crea una nueva cadena cada vez que lo invocas, de modo que estás creando 3 cadenas nuevas, temporales, en cada iteración del ciclo. Yo por eso usé   porque ese método hace internamente toda la búsqueda y te da la primera posición donde aparece el código.

BT, Haz una comparación entre el performance de ese for que pusiste en el último comentario, y el algoritmo que puse en mi primer comentario. Debe haber una gran diferencia con cadenas largas que tengan varias ocurrencias de la cadena a reemplazar.

Imagen de ezamudio

caracter

Por otra parte, si sabes que vas a reemplazar un solo caracter por otro caracter distinto, puedes hacer una búsqueda como la de tu for pero optimizada para un solo caracter:

 

micro-Benchmarck

 

tamaño de cadena1000
A 37ms
B 22ms
C 10ms

10000
A 70ms
B 88ms
C 73ms

100000
A 186 ms
B 4094 ms
C 5010 ms

200000
A 288ms
B 17628ms
C 19705ms

replace de StringBuilder es bastante lento para cadenas grandes.

Imagen de ezamudio

replace

  solamente reemplaza un caracter, cierto? Entonces la versión que deberías usar con StringBuilder es el último algoritmo que puse, el que trabaja directo con chars, a ver qué tal funciona ese:

 

y para los benchmarks, recuerda que siempre es necesario correr una vez todo el código que vas a benchmarkear y desechar esos tiempos, porque la primera ejecución es más lenta debido al JIT; luego ya corres el benchmark bien (todo eso en la misma ejecución del programa, para que sea la misma JVM obviamente).

mini-benchmark

 

D es realmente rapido, ahora usara setCharAt.