2010-10-01 15 views
13

tengo código de la siguiente manera:¿Es siempre una mala idea usar + para concatenar cadenas

String s = ""; 
for (My my : myList) { 
    s += my.getX(); 
} 

Findbugs siempre informa de error cuando hago esto.

+1

es getX(); devolviendo una cadena? –

+0

No creo que sea 'siempre' malo. Pero más a menudo, entonces, no hay alternativas que sean más adecuadas. – decompiled

+6

Definitivamente no es siempre malo usar concatenación con +. Sin embargo, es malo cuando haces un ciclo así. – ColinD

Respuesta

21

me gustaría utilizar + si está concatenando manualmente,

String word = "Hello"; 
word += " World!"; 

Sin embargo, si usted está iterando y concatenando Yo sugeriría StringBuilder,

StringBuilder sb = new StringBuilder(); 
for (My my : myList) { 
    sb.append(my.getX()); 
} 
+7

+1 - es una concatenación * en un bucle * que generalmente debe evitar. –

+0

Otro punto: en realidad puede ser más útil usar + en algunos casos, si hay cadenas literales que se concatenan, ya que una serie de literales concatenados se compilará como una cadena. No estoy seguro, dada la forma en que se divide en varias líneas, pero creo que el compilador optimizaría eso en 'String word =" ¡Hola mundo! '. – ColinD

+0

Está bien utilizar una concatenación como esta, si está seguro de que su aplicación nunca será localizada. Si planea traducirlo a un idioma extranjero, terminará con un defecto de localización. –

8

El objeto String es inmutable en Java. Cada + significa otro objeto. Podría usar StringBuffer para minimizar la cantidad de objetos creados.

+7

Java traduce la concatenación con + para usar un 'StringBuilder'. Solo necesita usar 'StringBuilder' usted mismo si está creando un bucle o construyendo una cadena usando una serie de llamadas a métodos o algo así. Además, 'StringBuffer' tiene una sobrecarga de seguridad de subprocesos que normalmente no necesita, por lo que' StringBuilder' es generalmente una mejor opción. – ColinD

+5

_Tony se escapa para leer sobre StringBuilder_ –

3

El compilador puede optimizar alguna cosa como

"foo" + "barra"

Para

StringBuilder s1 = new StringBuilder(); s1.append ("foo"). Append ("barra");

Sin embargo, esto todavía no es óptimo, ya que comienza con un tamaño predeterminado de 16. Al igual que con muchas cosas, debe encontrar sus cuellos de botella más grandes y avanzar hasta la lista. Sin embargo, no está de más estar en el hábito de usar un patrón de SB desde el principio, especialmente si se puede calcular un tamaño de inicialización óptimo.

+0

en realidad el * compilador * puede optimizar esto para simplemente '" foobar "' ... +1 para encontrar el cuello de botella –

3

La optimización prematura puede ser mala, ya que a menudo reduce la legibilidad y por lo general es completamente innecesaria. Use + si es más legible a menos que realmente tenga una preocupación primordial.

3

No es 'siempre malo' utilizar "+". Usar StringBuffer en todas partes puede hacer que el código sea realmente voluminoso.

Si alguien pone un montón de "+" en el medio de un ciclo intensivo, de tiempo crítico, me molestaría. Si alguien pusiera mucho "+" en un fragmento de código raramente utilizado, no me importaría.

1

yo diría uso plus en lo siguiente:

String c = "a" + "b"

Y el uso de la clase StringBuilder en cualquier otro lugar. Como ya se mencionó en el primer caso, será optimizado por el compilador y es más legible.

4

Cada vez que haces string+=string, se llama método como este:

private String(String s1, String s2) { 
    if (s1 == null) { 
     s1 = "null"; 
    } 
    if (s2 == null) { 
     s2 = "null"; 
    } 
    count = s1.count + s2.count; 
    value = new char[count]; 
    offset = 0; 
    System.arraycopy(s1.value, s1.offset, value, 0, s1.count); 
    System.arraycopy(s2.value, s2.offset, value, s1.count, s2.count); 
} 

En caso de StringBuilder, se trata de:

final void append0(String string) { 
    if (string == null) { 
     appendNull(); 
     return; 
    } 
    int adding = string.length(); 
    int newSize = count + adding; 
    if (newSize > value.length) { 
     enlargeBuffer(newSize); 
    } 
    string.getChars(0, adding, value, count); 
    count = newSize; 
} 

Como se puede concluir claramente, string + string crea una gran cantidad de por encima, y ​​en mi opinión se debe evitar si es posible.Si cree que utilizando StringBuilder es voluminoso o para el tiempo que puede simplemente hacer un método y utilizar de manera indirecta, como:

public static String scat(String... vargs) { 
    StringBuilder sb = new StringBuilder(); 

    for (String str : vargs) 
     sb.append(str); 

    return sb.toString(); 
} 

Y usarlo como:

String abcd = scat("a","b","c","d"); 

En C# Me han dicho que sus cerca lo mismo que string.Concat();. En su caso, sería conveniente escribir sobrecarga para el scat, como:

public static String scat(Collection<?> vargs) { 
    StringBuilder sb = new StringBuilder(); 

    for (Object str : vargs) 
     sb.append(str); 

    return sb.toString(); 
} 

Entonces se le puede llamar con:

result = scat(myList) 
1

Una de las razones por las FindBugs deben discutir sobre el uso de operador de concatenación (sea it "+" o "+ =") es localizable. En el ejemplo que diste no es tan evidente, pero en el caso del código siguiente que es:

String result = "Scanning found " + Integer.toString(numberOfViruses) + " viruses"; 

Si esto parece algo familiar, tiene que cambiar su estilo de codificación. El problema es que sonará muy bien en inglés, pero podría ser una pesadilla para los traductores. Eso es solo porque no puedes garantizar que el orden de la oración seguirá siendo el mismo después de la traducción: algunos idiomas se traducirán como "1 bla, bla", otros como "bla, bla, 3". En tales casos, siempre debe usar MessageFormat.format() para construir oraciones compuestas y usar el operador de concatenación es claramente un error de internacionalización.

BTW. Puse otro defecto i18n aquí, ¿podrías detectarlo?

0

El tiempo de ejecución de la concatenación de dos cadenas es proporcional a la longitud de las cadenas. Si se usa en un ciclo, el tiempo de ejecución siempre aumenta. Entonces, si se necesita concatenación en un bucle, es mejor usar StringBuilder como Anthony sugirió.

Cuestiones relacionadas