2014-07-04 15 views
19

Come ho capito, quando faccio il String baz = "foo" + "bar" + "123" il compilatore Java sostituisce internamente l'espressione con uno StringBuilder. Tuttavia il nostro insegnante ci ha detto che Java è buona norma utilizzare sempre un StringBuilder esplicitamente ...Quando si dovrebbe utilizzare in modo esplicito un oggetto StringBuilder?

Ho ragione nel ritenere sarò solo necessario utilizzare in modo esplicito StringBuilder quando concatenazione all'interno loop come indicato nella an answer to Stack Overflow question String builder vs string concatenation? Esistono altri casi in cui è necessario utilizzare esplicitamente uno StringBuilder anziché + o +=?

+5

'di utilizzare sempre un explicitly' StringBuilder - non è buona pratica. Sacrificerai la leggibilità del codice per il guadagno di prestazioni del 0,0000000000001%. Usa StringBuilder quando vuoi aggiungere in un ciclo migliaia di stringhe. –

+2

Non sono sicuro del motivo per cui l'insegnante java è così appassionata di usare StringBuilder. StringBuilder è bello e tutto tranne java lo gestisce internamente. – nafas

+10

L'insegnante ha torto. Hai ragione. –

risposta

35

È più generale di "loop interni": è ogni volta che si desidera eseguire la concatenazione su più istruzioni e non è necessario il risultato intermedio come stringa. Per esempio:

StringBuilder builder = new StringBuilder("Start"); 
if (someCondition) { 
    builder.append("Foo"); 
} 
if (someOtherCondition) { 
    builder.append("Bar"); 
} 
builder.append("End"); 
String result = builder.toString(); 

Mentre si potrebbe scrivere che come:

String result = "Start" + (someCondition ? "Foo" : "") 
    + (someOtherCondition ? "Bar" : "") + "End"; 

... che diventa difficile da leggere. E se ci sono più dichiarazioni all'interno dei corpi if, potrebbe non essere nemmeno fattibile.

correggere qualcosa all'interno della vostra domanda però:

A quanto ho capito, quando faccio String baz = + "bar" "pippo" + "123" il compilatore java sostituisce internamente l'espressione con uno StringBuilder .

No, quando si scrive che l'espressione il compilatore riconosce che si tratta di una fase di compilazione costante, e lo sostituisce con

String baz = "foobar123"; 

Questa è una buona ragione non utilizzare in modo esplicito un StringBuilder - il codice di cui sopra è chiaramente più efficace al momento dell'esecuzione di

String baz = new StringBuilder("foo").append("bar").append("123").toString(); 

Quando non è una costante in fase di compilazione, il compilatore Java eseguirà la concatenazione utilizzando un StringBuilder, in genere lasciandovi un codice più comprensibile che non con l'uso esplicito di StringBuilder, ma senza alcun impatto sulle prestazioni. Ho il sospetto che il tuo insegnante non capisca correttamente la concatenazione di stringhe, o semplicemente abbia letto da qualche altra parte che dovresti usare StringBuilder senza comprendere completamente quando è appropriato il.

+3

Grazie a te ea tutti gli altri per la risposta dettagliata, ora tutto è molto più chiaro. sei Jon Skeet l'autore della libreria dernc.c? perché sto usando una porta java di questo nel mio progetto attuale :) user2711115

+0

Ci siamo imbattuti in questo - non credo che C# usi un StringBuilder sotto di default? Qualche idea sul perché la differenza tra C# e Java - mi sono chiesto in precedenza perché C# non si prenda cura di questo per te. – Ian

+0

@Ian: C# usa 'String.Concat' piuttosto che un' StringBuilder', ma è lo stesso tipo di principio. –

1

Obi Wan ha detto che solo Sith pensa in assoluti o qualcosa di simile ...

E 'bene sapere che il compilatore Java sostituisce internamente "+" su stringhe con l'utilizzo del StringBuilder. Ecco a cosa servono i compilatori: per semplificare la vita.

A meno che non si dispone di loop, come nel caso collegato, o condizionali dall'esempio di Jon Skeet, è in primo luogo la questione della leggibilità e la facilità di maintanance.

Sostituzione

return "User " + userName + " said"; 

con

new StringBuilder().append("User ").append(userName).append(" said").toString(); 

rende il codice più a lungo, probabilmente più difficile da modificare, è più probabile che forzare interruzioni di linea, e ti dà maggiori prestazioni.

Tuttavia, quando l'aggiunta si applica non solo alle stringhe, ma sono presenti numeri, probabilmente la soluzione con StringBuilder a volte può essere più leggibile.

return "User" + a + b + " said: " + (c + d); 

possono essere più fuorviante in quanto:

return new StringBuilder().append("User ").append(a).append(b) 
    .append(" said: ").append(c+d).toString(); 

Ma è in primo luogo la questione di opinione e di stile di codifica. "Should" non è una buona parola qui.

+0

Mi piacerebbe solo ripetermi - "return" User "+ a + b +" ha detto: "+ (c + d);" mi è ancora molto più leggibile rispetto a quest'ultima versione, specialmente se i numeri sono nominati sensibilmente - si noti inoltre che si utilizzano raramente due numeri uno accanto all'altro * senza alcun separatore tra *; Non ho visto alcun esempio di vita reale che userebbe SB per * aumentare * la chiarezza - direi che è buono a * offuscare * le cose, però. – vaxquis

1

Sono anche buoni per implementare cose come la parola chiave 'out' di C# con una stringa. Esempio

public int getInt(StringBuilder error) 
{ 
    int retVal = 0; 

    if (someErrorOccured) 
     error.append("Couldn't get int because of..."); 
    else 
     retVal = whatItsSupposedToBe; 

    return retVal; 
} 
Problemi correlati