Pregunta Mejores prácticas / rendimiento: mezclando StringBuilder.append con String.concat


Estoy tratando de entender cuál es la mejor práctica y por qué para concatenar literales de cadena y variables para diferentes casos. Por ejemplo, si tengo un código como este

StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
    .append(B_String).append("CCCCCCCCCCC").append(D_String)
    .append("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
    .append("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");

¿Es esta la manera de hacerlo? De esta publicación, Noté que el + operador en cadenas crea una nueva instancia de StringBuilder, concatena los operandos y devuelve una conversión de cadena, que parece mucho más trabajo que simplemente llamar .append(); entonces si eso es cierto, entonces eso está fuera de discusión. Pero que pasa String.concat()? ¿Es correcto usar .append() para cada concatenación? O solo para variables, y los literales están bien para anexar .concat()?

StringBuilder sb = new StringBuilder("AAAAAAAAAAAAA")
    .append(B_String.concat("CCCCCCCCCCC")).append(D_String
    .concat("EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE")
    .concat("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"));

¿Cuáles son las reglas generales de las mejores prácticas y el rendimiento para abordar estas situaciones? Es mi suposición correcta en + y realmente no debería ser usado?


73
2018-04-09 19:51


origen


Respuestas:


+ operador

String s = s1 + s2

Detrás de escena esto se traduce a:

String s = new StringBuilder(s1).append(s2).toString();

Imagine cuánto trabajo adicional agrega si tiene s1 + s2 aquí:

stringBuilder.append(s1 + s2)

en lugar de:

stringBuilder.append(s1).append(s2)

Varias cadenas con +

Vale la pena notar que:

String s = s1 + s2 + s3 + ... +sN

se traduce a:

String s = new StringBuilder(s1).append(s2).append(s3)...apend(sN).toString();

concat()

String s = s1.concat(s2);

String crea char[] matriz que puede adaptarse a ambos s1 y s2. Copias s1 y s2 contenidos a esta nueva matriz. En realidad requiere menos trabajo entonces + operador.

StringBuilder.append()

Mantiene un interno char[] matriz que crece cuando sea necesario. Sin extra char[] se crea si el interno es lo suficientemente grande.

stringBuilder.append(s1.concat(s2))

también está funcionando mal porque s1.concat(s2) crea un extra char[] matriz y copias s1 y s2 solo para copiar los nuevos contenidos de la matriz a internos StringBuilder  char[].

Dicho esto, deberías usar append() todo el tiempo y anexe cadenas sin formato (su primer fragmento de código es correcto).


159
2018-04-09 20:00



El compilador optimiza la + concatenación.

Asi que

int a = 1;
String s = "Hello " + a;

se transforma en

new StringBuilder().append("Hello ").append(1).toString();

Hay un excelente tema aquí explicando por qué debería usar el operador +.


14
2018-04-09 19:57



La optimización se realiza automáticamente por el compilador.

El compilador Java2 convertirá automáticamente lo siguiente:

String s = s1 + s2; 

a

String s = (new StringBuffer()).append(s1).append(s2).toString();

Tomado directamente de la Prácticas recomendadas de Java en el sitio web de Oracles.


3
2018-05-12 19:41



Siempre debes usar append.

concat crea un nuevo String así que es bastante parecido + Creo.

Si tu concat o usar + con 2 String final, la JVM puede optimizar, por lo que es lo mismo que hacer agregar en este caso.


2
2018-04-09 19:58



Si utiliza exactamente dos cadenas, use String.concat (crea una nueva cadena creando una nueva matriz de caracteres que se adapte a ambas cadenas y copie las dos matrices de cadenas de caracteres en ella).

Si combina varias cadenas (más de dos) en una línea, use + o StringBuilder.append, no importa, ya que el compilador convierte + a StringBuilder.append. Esto es bueno para múltiples cadenas porque mantiene una matriz de caracteres que crece según sea necesario.

Si concat varias cadenas en múltiples líneas crea un StringBuilder y utiliza el método de agregar. Al final, cuando haya terminado de anexar cadenas a StringBuilder, use su método .toString () para crear una cadena. Para la concatenación en múltiples líneas, esto es más rápido que el segundo método, ya que el segundo método crearía un nuevo StringBuilder en cada línea, anexaría las cadenas y luego volvería a Cadena, mientras que el tercer método solo usaría un StringBuilder para todo.


1
2018-01-27 10:03



Utilizar + el operador es la mejor práctica, también es simple y legible.

El lenguaje Java proporciona soporte especial para la cadena   operador de concatenación (+), y para la conversión de otros objetos a   instrumentos de cuerda. La concatenación de cadenas se implementa a través de   Clase StringBuilder (o StringBuffer) y su método de adición.

Documento oficial: https://docs.oracle.com/javase/8/docs/api/java/lang/String.html


0
2017-08-10 03:34



en el nivel de código de bytes no es diferente y no estamos comprometiendo la effeciancia allí. En caso de ejecutar el nivel de código de bytes, debe pasar por el método de sobrecarga del operador no en línea para + llamando a append. luego en el nivel de lenguaje ensamblador (Java está escrito en C y C produce ensambles similares al ensamblado, habrá una llamada de registro adicional para almacenar + llamada de método en la pila y habrá un empuje adicional. (en realidad, el compilador cruzado podría optimizar el operador + llame, en ese caso, para que no haya diferencia con la eficiencia.)

Es una buena práctica tener una forma de aumentar la legibilidad. :)


0
2017-09-26 14:26