Pregunta Usando String o StringBuffer en Java: ¿cuál es mejor?


Leí mucho sobre el uso de StringBuffer y String, especialmente cuando se trata de concatenación en Java y si uno es seguro para subprocesos o no.

Entonces, en varios métodos de Java, ¿cuáles deberían ser utilizados?

Por ejemplo, en un PreparedStatement, la consulta debe ser un StringBuffer:

    String query = ("SELECT * " +
                    "FROM User " +
                    "WHERE userName = ?;");

    try {
        ps = connection.prepareStatement(query);

Y luego otra vez, en una utilidad de cadena de métodos como:

public static String prefixApostrophesWithBackslash(String stringIn) {
    String stringOut = stringIn.replaceAll("'", "\\\\'");
    return stringOut;
}

Y:

 // Removes a char from a String.
public static String removeChar(String stringIn, char c) {
    String stringOut = ("");
    for (int i = 0; i < stringIn.length(); i++) {
        if (stringIn.charAt(i) != c) {
            stringOut += stringIn.charAt(i);
        }
    }
    return stringOut;
}

¿Debo usar StringBuffers? Especialmente donde repalceAll no está disponible para tales objetos de todos modos.

Gracias

Sr. Morgan.

Gracias por todos los consejos. StringBuffers ha sido reemplazado por StringBuilders y Strings reemplazado por StringBuilders donde lo he pensado mejor.


5
2017-07-19 07:24


origen


Respuestas:


Casi nunca necesitas usar StringBuffer.

En lugar de StringBuffer usted probablemente quiere decir StringBuilder. Un StringBuffer es como un StringBuilder, excepto que también ofrece seguridad de subprocesos. Esta seguridad de subprocesos rara vez se necesita en la práctica y solo hará que el código se ejecute más lentamente.

Su pregunta no parece ser sobre String vs StringBuffer, sino sobre el uso de métodos integrados o la implementación del código usted mismo. Si hay un método incorporado que hace exactamente lo que desea, probablemente debería usarlo. Lo más probable es que esté mucho mejor optimizado que el código que escribiría.


7
2017-07-19 07:28



No hay una respuesta simple (aparte de repetir el mantra de StringBuilder versus StringBuffer ...). Realmente has entendido bastante sobre lo que sucede "debajo del capó" para elegir la solución más eficiente.

En tu primer ejemplo, String es el camino a seguir. El compilador de Java puede generar código bastante óptimo (usando un StringBuilder si es necesario) para cualquier expresión consistente en una secuencia de concatenaciones de cadenas. Y, si las cadenas que están concatenadas son todas constantes o literales, el compilador puede hacer la concatenación en el momento de la compilación.

En su segundo ejemplo, no está del todo claro si String o StringBuilder sería mejor ... o si serían aproximadamente equivalentes. Uno necesitaría mirar el código del java.util.regex.Matcher clase para resolver esto

EDITAR - Miré el código, y en realidad hace poca diferencia si usas un String o StringBuilder como la fuente. Internamente el Matcher.replaceAll el método crea un nuevo StringBuilder y lo llena agregando fragmentos de la cadena de origen y la cadena de reemplazo.

En tu tercer ejemplo, un StringBuilder claramente sería lo mejor Un compilador Java de la generación actual no puede optimizar el código (como está escrito) para evitar crear una nueva Cadena a medida que se agrega cada carácter.


3
2017-07-19 07:49



Para el siguiente segmento de código

 // Removes a char from a String.
public static String removeChar(String stringIn, char c) {
    String stringOut = ("");
    for (int i = 0; i < stringIn.length(); i++) {
        if (stringIn.charAt(i) != c) {
            stringOut += stringIn.charAt(i);
        }
    }
    return stringOut;
}

Podrías hacer stringIn.replaceAll(c+"","")


1
2017-07-19 07:29



Incluso en el código MT, es inusual tener múltiples hilos que añadan cosas a una cadena. StringBuilder casi siempre se prefiere a StringBuffer.


1
2017-07-19 07:43



Los compiladores modernos optimizan el código ya. Así que algunas adiciones de String se optimizarán para usar StringBuilder y podemos mantener las adiciones de String si pensamos que aumenta la legibilidad.

Ejemplo 1:

String query = ("SELECT * " +
                "FROM User " +
                "WHERE userName = ?;");

será optimizado para algo así como:

StringBuiler sb = new StringBuilder();
sb.append("SELECT * ");
sb.append("FROM User ");
sb.append("WHERE userName = ?;");
String query = sb.toString();

Ejemplo 2:

String numbers = "";
for (int i = 0;i < 20; i++)
  numbers = numbers + i;

Esto no se puede optimizar y deberíamos usar un StringBuilder en el código.


Hice esta observación para SUN jdk1.5 +. Así que para versiones anteriores de Java o diferentes jdks puede ser diferente. Allí podría ser salvado codificar siempre StringBuilder (o StringBuffer para jdk 1.4.2 y anteriores).


1
2017-07-19 08:00



Para los casos que pueden considerarse de un solo hilo, lo mejor sería StringBuilder. No agrega ninguna sobrecarga de sincronización, mientras que StringBuffer sí lo hace.

La concatenación de cadenas por el operador '+' es "buena" solo cuando es perezoso para usar StringBuilder o simplemente desea que el código sea legible y que sea aceptable desde el punto de vista del rendimiento, como en el mensaje de registro de inicio "LOG.info (" Instancia inicial "+ inst_id +" de "+ nombre_apl);"


0
2017-07-19 07:31