Domanda

Dato il 2 toString() implementazioni di seguito, quale è preferibile:

public String toString(){
    return "{a:"+ a + ", b:" + b + ", c: " + c +"}";
}

O

public String toString(){
    StringBuilder sb = new StringBuilder(100);
    return sb.append("{a:").append(a)
          .append(", b:").append(b)
          .append(", c:").append(c)
          .append("}")
          .toString();
}

?

Ancora più importante, dato che abbiamo solo 3 proprietà, potrebbe non fare la differenza, ma da quale punto passeresti? + concat a StringBuilder?

È stato utile?

Soluzione

La versione 1 è preferibile perché è più breve e il compilatore infatti lo trasformerà nella versione 2 - nessuna differenza di prestazioni.

Ancora più importante, abbiamo solo 3 proprietà che potrebbe non fare la differenza, ma a che punto passa da Concat a Builder?

Nel punto in cui stai concatenando in un ciclo, di solito è quando il compilatore non può sostituire StringBuilder da solo.

Altri suggerimenti

La chiave è se si sta scrivendo un singolo concatenazione di tutto in un luogo o ad accumulare nel tempo.

Per l'esempio che ha dato, non c'è nessun punto in modo esplicito utilizzando StringBuilder. (Guarda il codice compilato per il primo caso.)

Ma se si sta costruendo una stringa per esempio all'interno di un ciclo, utilizzare StringBuilder.

Per chiarire, partendo dal presupposto che hugeArray contiene migliaia di stringhe, codice come questo:

...
String result = "";
for (String s : hugeArray) {
    result = result + s;
}

è molto tempo e la memoria-dispendioso rispetto a:

...
StringBuilder sb = new StringBuilder();
for (String s : hugeArray) {
    sb.append(s);
}
String result = sb.toString();

Io preferisco:

String.format( "{a: %s, b: %s, c: %s}", a, b, c );

... perché è breve e leggibile.

Vorrei non ottimizzare questo per la velocità a meno che non lo si utilizza all'interno di un ciclo con un altissimo numero di ripetizione e hanno misurato la differenza di prestazioni.

Sono d'accordo, che se si deve produrre un sacco di parametri, questo modulo può diventare confuso (come uno dei commenti dicono). In questo caso mi piacerebbe passare a una forma più leggibile (magari utilizzando ToStringBuilder di apache-commons -. prese dalla risposta di Matt b) e ignorare ancora una volta le prestazioni

Nella maggior parte dei casi, non si vedrà una differenza reale tra i due approcci, ma è facile costruire uno scenario peggiore come questo:

public class Main
{
    public static void main(String[] args)
    {
        long now = System.currentTimeMillis();
        slow();
        System.out.println("slow elapsed " + (System.currentTimeMillis() - now) + " ms");

        now = System.currentTimeMillis();
        fast();
        System.out.println("fast elapsed " + (System.currentTimeMillis() - now) + " ms");
    }

    private static void fast()
    {
        StringBuilder s = new StringBuilder();
        for(int i=0;i<100000;i++)
            s.append("*");      
    }

    private static void slow()
    {
        String s = "";
        for(int i=0;i<100000;i++)
            s+="*";
    }
}

L'output è:

slow elapsed 11741 ms
fast elapsed 7 ms

Il problema è che a + = aggiungere a una stringa ricostruisce una nuova stringa, quindi il costo è qualcosa di lineare per la lunghezza delle corde (somma dei due).

- alla tua domanda:

Il secondo approccio sarebbe più veloce, ma è meno leggibile e più difficile da mantenere. Come ho già detto, nel tuo caso specifico si sarebbe probabilmente non vedere la differenza.

Ho avuto anche scontrarsi con il mio capo sul fatto se utilizzare o accodamento + .Come stanno usando Aggiungi (io ancora non posso figura fuori come si suol dire ogni volta che viene creato un nuovo oggetto). Così ho pensato di fare un po 'di R & D.Although amo Michael Borgwardt spiegazione, ma solo voluto mostrare una spiegazione se qualcuno sarà davvero bisogno di sapere in futuro.

/**
 *
 * @author Perilbrain
 */
public class Appc {
    public Appc() {
        String x = "no name";
        x += "I have Added a name" + "We May need few more names" + Appc.this;
        x.concat(x);
        // x+=x.toString(); --It creates new StringBuilder object before concatenation so avoid if possible
        //System.out.println(x);
    }

    public void Sb() {
        StringBuilder sbb = new StringBuilder("no name");
        sbb.append("I have Added a name");
        sbb.append("We May need few more names");
        sbb.append(Appc.this);
        sbb.append(sbb.toString());
        // System.out.println(sbb.toString());
    }
}

e lo smontaggio di classe superiore esce come

 .method public <init>()V //public Appc()
  .limit stack 2
  .limit locals 2
met001_begin:                                  ; DATA XREF: met001_slot000i
  .line 12
    aload_0 ; met001_slot000
    invokespecial java/lang/Object.<init>()V
  .line 13
    ldc "no name"
    astore_1 ; met001_slot001
  .line 14

met001_7:                                      ; DATA XREF: met001_slot001i
    new java/lang/StringBuilder //1st object of SB
    dup
    invokespecial java/lang/StringBuilder.<init>()V
    aload_1 ; met001_slot001
    invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
    ldc "I have Added a nameWe May need few more names"
    invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
    aload_0 ; met001_slot000
    invokevirtual java/lang/StringBuilder.append(Ljava/lang/Object;)Ljava/lan\
g/StringBuilder;
    invokevirtual java/lang/StringBuilder.toString()Ljava/lang/String;
    astore_1 ; met001_slot001
  .line 15
    aload_1 ; met001_slot001
    aload_1 ; met001_slot001
    invokevirtual java/lang/String.concat(Ljava/lang/String;)Ljava/lang/Strin\
g;
    pop
  .line 18
    return //no more SB created
met001_end:                                    ; DATA XREF: met001_slot000i ...

; ===========================================================================

;met001_slot000                                ; DATA XREF: <init>r ...
    .var 0 is this LAppc; from met001_begin to met001_end
;met001_slot001                                ; DATA XREF: <init>+6w ...
    .var 1 is x Ljava/lang/String; from met001_7 to met001_end
  .end method
;44-1=44
; ---------------------------------------------------------------------------


; Segment type: Pure code
  .method public Sb()V //public void Sb
  .limit stack 3
  .limit locals 2
met002_begin:                                  ; DATA XREF: met002_slot000i
  .line 21
    new java/lang/StringBuilder
    dup
    ldc "no name"
    invokespecial java/lang/StringBuilder.<init>(Ljava/lang/String;)V
    astore_1 ; met002_slot001
  .line 22

met002_10:                                     ; DATA XREF: met002_slot001i
    aload_1 ; met002_slot001
    ldc "I have Added a name"
    invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
    pop
  .line 23
    aload_1 ; met002_slot001
    ldc "We May need few more names"
    invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
    pop
  .line 24
    aload_1 ; met002_slot001
    aload_0 ; met002_slot000
    invokevirtual java/lang/StringBuilder.append(Ljava/lang/Object;)Ljava/lan\
g/StringBuilder;
    pop
  .line 25
    aload_1 ; met002_slot001
    aload_1 ; met002_slot001
    invokevirtual java/lang/StringBuilder.toString()Ljava/lang/String;
    invokevirtual java/lang/StringBuilder.append(Ljava/lang/String;)Ljava/lan\
g/StringBuilder;
    pop
  .line 28
    return
met002_end:                                    ; DATA XREF: met002_slot000i ...


;met002_slot000                                ; DATA XREF: Sb+25r
    .var 0 is this LAppc; from met002_begin to met002_end
;met002_slot001                                ; DATA XREF: Sb+9w ...
    .var 1 is sbb Ljava/lang/StringBuilder; from met002_10 to met002_end
  .end method
;96-49=48
; ---------------------------------------------------------------------------

Da quanto sopra due codici Voi potete vedere Michael è right.In ogni caso viene creato un solo oggetto SB.

Da Java 1.5, semplice concatenazione linea con "+" e StringBuilder.append () genera esattamente lo stesso bytecode.

Quindi, per il bene della leggibilità del codice, usare "+".

2 eccezioni:

  • ambiente multithread: StringBuffer
  • concatenazione in loop: StringBuilder / StringBuffer

Usando ultima versione di Java (1.8) lo smontaggio (javap -c) mostra l'ottimizzazione introdotto da compilatore. + così sb.append() genererà codice molto simile. Tuttavia, sarà utile ispezionare il comportamento se stiamo usando + in un ciclo for.

Aggiunta di stringhe utilizzando + in un ciclo for

Java:

public String myCatPlus(String[] vals) {
    String result = "";
    for (String val : vals) {
        result = result + val;
    }
    return result;
}

ByteCode: (for ciclo estratto)

12: iload         5
14: iload         4
16: if_icmpge     51
19: aload_3
20: iload         5
22: aaload
23: astore        6
25: new           #3                  // class java/lang/StringBuilder
28: dup
29: invokespecial #4                  // Method java/lang/StringBuilder."<init>":()V
32: aload_2
33: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: aload         6
38: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: invokevirtual #6                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
44: astore_2
45: iinc          5, 1
48: goto          12

Aggiunta di stringhe utilizzando stringbuilder.append

Java:

public String myCatSb(String[] vals) {
    StringBuilder sb = new StringBuilder();
    for(String val : vals) {
        sb.append(val);
    }
    return sb.toString();
}

ByteCdoe: (for ciclo estratto)

17: iload         5
19: iload         4
21: if_icmpge     43
24: aload_3
25: iload         5
27: aaload
28: astore        6
30: aload_2
31: aload         6
33: invokevirtual #5                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: pop
37: iinc          5, 1
40: goto          17
43: aload_2

C'è un po 'di differenza lampante però. Nel primo caso, in cui è stato utilizzato +, nuovo StringBuilder viene creata per ogni ciclo for iterazione e il risultato viene memorizzato effettuando una chiamata toString() (da 29 a 41). Così si sta generando stringhe intermedi che il vostro davvero non hanno bisogno durante l'utilizzo dell'operatore + in loop for.

In Java 9 versione 1 dovrebbe essere più veloce perché viene convertito in invokedynamic chiamata. Maggiori dettagli possono essere trovati in Jep-280 :

  

L'idea è quella di sostituire l'intero ballo StringBuilder append con una semplice chiamata invokedynamic a java.lang.invoke.StringConcatFactory, che accetta i valori nel bisogno di concatenazione.

Apache Commons Lang-ha un ToStringBuilder classe che è super facile da usare. Si fa un bel lavoro di entrambi gestire l'append-logica, così come la formattazione di come si desidera che il toString a guardare.

public void toString() {
     ToStringBuilder tsb =  new ToStringBuilder(this);
     tsb.append("a", a);
     tsb.append("b", b)
     return tsb.toString();
}

Tornerà in uscita che assomiglia com.blah.YourClass@abc1321f[a=whatever, b=foo].

O in una forma più condensata utilizzando il concatenamento:

public void toString() {
     return new ToStringBuilder(this).append("a", a).append("b", b").toString();
}

In alternativa, se si desidera utilizzare la riflessione per includere tutti i campi della classe:

public String toString() {
    return ToStringBuilder.reflectionToString(this);
}

È inoltre possibile personalizzare lo stile del ToString, se si desidera.

Per motivi di prestazioni, l'uso di += (String concatenazione) è scoraggiato. Il motivo per cui è: Java String è un immutabile, ogni volta che un nuovo concatenamento è fatto un nuovo String viene creato (quello nuovo ha un'impronta digitale diverso da quello più vecchio già nella piscina String ). La creazione di nuove stringhe mette pressione sul GC e rallenta il programma: creazione di oggetti è costoso.

Di seguito il codice dovrebbe rendere più pratico e chiaro allo stesso tempo.

public static void main(String[] args) 
{
    // warming up
    for(int i = 0; i < 100; i++)
        RandomStringUtils.randomAlphanumeric(1024);
    final StringBuilder appender = new StringBuilder();
    for(int i = 0; i < 100; i++)
        appender.append(RandomStringUtils.randomAlphanumeric(i));

    // testing
    for(int i = 1; i <= 10000; i*=10)
        test(i);
}

public static void test(final int howMany) 
{
    List<String> samples = new ArrayList<>(howMany);
    for(int i = 0; i < howMany; i++)
        samples.add(RandomStringUtils.randomAlphabetic(128));

    final StringBuilder builder = new StringBuilder();
    long start = System.nanoTime();
    for(String sample: samples)
        builder.append(sample);
    builder.toString();
    long elapsed = System.nanoTime() - start;
    System.out.printf("builder - %d - elapsed: %dus\n", howMany, elapsed / 1000);

    String accumulator = "";
    start = System.nanoTime();
    for(String sample: samples)
        accumulator += sample;
    elapsed = System.nanoTime() - start;
    System.out.printf("concatenation - %d - elapsed: %dus\n", howMany, elapsed / (int) 1e3);

    start = System.nanoTime();
    String newOne = null;
    for(String sample: samples)
        newOne = new String(sample);
    elapsed = System.nanoTime() - start;
    System.out.printf("creation - %d - elapsed: %dus\n\n", howMany, elapsed / 1000);
}

Risultati per una corsa sono di seguito riportati.

builder - 1 - elapsed: 132us
concatenation - 1 - elapsed: 4us
creation - 1 - elapsed: 5us

builder - 10 - elapsed: 9us
concatenation - 10 - elapsed: 26us
creation - 10 - elapsed: 5us

builder - 100 - elapsed: 77us
concatenation - 100 - elapsed: 1669us
creation - 100 - elapsed: 43us

builder - 1000 - elapsed: 511us
concatenation - 1000 - elapsed: 111504us
creation - 1000 - elapsed: 282us

builder - 10000 - elapsed: 3364us 
concatenation - 10000 - elapsed: 5709793us
creation - 10000 - elapsed: 972us

Non considerando i risultati 1 di concatenazione (JIT non era ancora facendo il suo lavoro), anche per 10 concatenazioni la pena di prestazioni è rilevante; per migliaia di concatenazioni, la differenza è enorme.

Lezioni apprese da questo molto veloce esperimento (facilmente riproducibile con il codice di cui sopra): non usare mai la += per concatenare le stringhe insieme, anche in casi molto di base in cui sono necessarie alcune concatenazioni (come detto, la creazione di nuove stringhe è costoso e comunque mette pressione sul GC).

Fare il metodo toString leggibile che puoi!

L'unica eccezione a questo nel mio libro è se si può dimostrare a me che consuma ingenti risorse :) (Sì, questo significa profiling)

Si noti inoltre che il compilatore Java 5 genera codice più veloce rispetto al metodo scritto a mano "StringBuffer" utilizzato nelle versioni precedenti di Java. Se si utilizza "+" questo e miglioramenti futuri viene gratuitamente.

Sembra che ci sia un certo dibattito se l'utilizzo di StringBuilder è ancora necessaria con i compilatori correnti. Così ho pensato che ti darò i miei 2 centesimi di esperienza.

Ho un set di risultati JDBC di 10k record (sì, ho bisogno di tutti in un unico lotto.) Utilizzando l'operatore + dura circa 5 minuti sulla mia macchina con Java 1.8. Utilizzando stringBuilder.append("") richiede meno di un secondo per la stessa query.

Quindi, la differenza è enorme. All'interno di un StringBuilder ciclo è molto più veloce.

Si veda l'esempio qui sotto:

//java8
static void main(String[] args) {
    case1();//str.concat
    case2();//+=
    case3();//StringBuilder
}

static void case1() {
    List<Long> savedTimes = new ArrayList();
    long startTimeAll = System.currentTimeMillis();
    String str = "";
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        long startTime = System.currentTimeMillis();
        str = str.concat(UUID.randomUUID()+"---");
        saveTime(savedTimes, startTime);
    }
    System.out.println("Created string of length:"+str.length()+" in "+(System.currentTimeMillis()-startTimeAll)+" ms");
}

static void case2() {
    List<Long> savedTimes = new ArrayList();
    long startTimeAll = System.currentTimeMillis();
    String str = "";
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        long startTime = System.currentTimeMillis();
        str+=UUID.randomUUID()+"---";
        saveTime(savedTimes, startTime);
    }        
    System.out.println("Created string of length:"+str.length()+" in "+(System.currentTimeMillis()-startTimeAll)+" ms");
}

static void case3() {
    List<Long> savedTimes = new ArrayList();
    long startTimeAll = System.currentTimeMillis();
    StringBuilder str = new StringBuilder("");
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        long startTime = System.currentTimeMillis();
        str.append(UUID.randomUUID()+"---");
        saveTime(savedTimes, startTime);
    }        
    System.out.println("Created string of length:"+str.length()+" in "+(System.currentTimeMillis()-startTimeAll)+" ms");

}

static void saveTime(List<Long> executionTimes, long startTime) {
        executionTimes.add(System.currentTimeMillis()-startTime);
        if(executionTimes.size()%CALC_AVG_EVERY == 0) {
            out.println("average time for "+executionTimes.size()+" concatenations: "+
                    NumberFormat.getInstance().format(executionTimes.stream().mapToLong(Long::longValue).average().orElseGet(()->0))+
                    " ms avg");
            executionTimes.clear();
        }
}

Output:

  

tempo medio di 10000 concatenazioni: 0,096 ms avg
  tempo medio di 10000 concatenazioni: 0,185 ms avg
  tempo medio di 10000 concatenazioni: 0,327 ms avg
  tempo medio di 10000 concatenazioni: 0,501 ms avg
  tempo medio di 10000 concatenazioni: 0,656 ms avg
  stringa creata di lunghezza: 1950000 in 17745 ms
  tempo medio di 10000 concatenazioni: 0,21 ms avg
  tempo medio di 10000 concatenazioni: 0,652 ms avg
  tempo medio di 10000 concatenazioni: 1.129 ms avg
  tempo medio di 10000 concatenazioni: 1.727 ms avg
  tempo medio di 10000 concatenazioni: 2.302 ms avg
  stringa creata di lunghezza: 1950000 in 60279 ms
  tempo medio di 10000 concatenazioni: 0.002 ms avg
  tempo medio di 10000 concatenazioni: 0.002 ms avg
  tempo medio di 10000 concatenazioni: 0.002 ms avg
  tempo medio di 10000 concatenazioni: 0.002 ms avg
  tempo medio di 10000 concatenazioni: 0.002 ms avg
  stringa creata di lunghezza: 1950000 in 100 ms

Con l'aumentare della lunghezza della corda, così fa il tempo di concatenazione.
È qui che è sicuramente necessaria l'StringBuilder.
Come si vede, la concatenazione:. UUID.randomUUID()+"---", in realtà non influisce sul tempo

PS: non credo Quando usare StringBuilder in Java è davvero un duplicato di questo.
Questa domanda parla toString() che il più delle volte non esegue concatenazioni di stringhe enormi.

Performance saggio concatenazione di stringhe con '+' è più costoso perché deve fare una nuova copia di String dal stringhe sono immutabili in Java. Questo gioca ruolo particolare se la concatenazione è molto frequente, ad esempio: all'interno di un ciclo. In seguito è quello che la mia idea suggerisce quando tento di fare una cosa del genere:

entrare descrizione dell'immagine qui

Regole generali:

  • All'interno di un singolo assegnazione delle stringhe, mediante concatenazione della stringa va bene.
  • Se stai loop per costruire un grande blocco di dati di carattere, andare per StringBuffer.
  • Uso + = on a String sta andando sempre essere meno efficiente rispetto all'utilizzo di uno StringBuffer, quindi dovrebbe suonare campanelli d'allarme - ma in alcuni casi l'ottimizzazione guadagnato sarà trascurabile rispetto ai problemi di leggibilità, in modo da usare il buon senso.

Ecco un bel Jon Skeet blog intorno a questo argomento.

Posso sottolineare che, se si sta andando a iterare su una collezione e l'uso StringBuilder, si consiglia di controllare Apache Commons Lang e StringUtils.join () (in diversi gusti)?

A prescindere prestazioni, sarà risparmiare dover creare StringBuilders e per i loop per quello che sembra la milionesima di tempo.

Ho confrontato quattro approccio diverso per confrontare le prestazioni. Io proprio non so cosa succede a GC, ma la cosa importante per me è il tempo. Compiler è importante fattore di here.I usato jdk1.8.0_45 sotto la piattaforma window8.1.

concatWithPlusOperator = 8
concatWithBuilder = 130
concatWithConcat = 127
concatStringFormat = 3737
concatWithBuilder2 = 46

public class StringConcatenationBenchmark {

private static final int MAX_LOOP_COUNT = 1000000;

public static void main(String[] args) {

    int loopCount = 0;
    long t1 = System.currentTimeMillis();
    while (loopCount < MAX_LOOP_COUNT) {
        concatWithPlusOperator();
        loopCount++;
    }
    long t2 = System.currentTimeMillis();
    System.out.println("concatWithPlusOperator = " + (t2 - t1));

    long t3 = System.currentTimeMillis();
    loopCount = 0;
    while (loopCount < MAX_LOOP_COUNT) {
        concatWithBuilder();
        loopCount++;
    }
    long t4 = System.currentTimeMillis();
    System.out.println("concatWithBuilder = " + (t4 - t3));

    long t5 = System.currentTimeMillis();
    loopCount = 0;
    while (loopCount < MAX_LOOP_COUNT) {
        concatWithConcat();
        loopCount++;
    }
    long t6 = System.currentTimeMillis();
    System.out.println("concatWithConcat = " + (t6 - t5));

    long t7 = System.currentTimeMillis();
    loopCount = 0;
    while (loopCount < MAX_LOOP_COUNT) {
        concatStringFormat();
        loopCount++;
    }
    long t8 = System.currentTimeMillis();
    System.out.println("concatStringFormat = " + (t8 - t7));

    long t9 = System.currentTimeMillis();
    loopCount = 0;
    while (loopCount < MAX_LOOP_COUNT) {
        concatWithBuilder2();
        loopCount++;
    }
    long t10 = System.currentTimeMillis();
    System.out.println("concatWithBuilder2 = " + (t10 - t9));
}

private static void concatStringFormat() {
    String s = String.format("%s %s %s %s ", "String", "String", "String", "String");
}

private static void concatWithConcat() {
    String s = "String".concat("String").concat("String").concat("String");
}

private static void concatWithBuilder() {
    StringBuilder builder=new StringBuilder("String");
    builder.append("String").append("String").append("String");
    String s = builder.toString();
}

private static void concatWithBuilder2() {
    String s = new StringBuilder("String").append("String").append("String").append("String").toString();
}

private static void concatWithPlusOperator() {
    String s = "String" + "String" + "String" + "String";
}
}

Ecco quello che ho controllato Java8

  • Utilizzo di concatenazione di stringhe
  • Uso StringBuilder

    long time1 = System.currentTimeMillis();
    usingStringConcatenation(100000);
    System.out.println("usingStringConcatenation " + (System.currentTimeMillis() - time1) + " ms");
    
    time1 = System.currentTimeMillis();
    usingStringBuilder(100000);
    System.out.println("usingStringBuilder " + (System.currentTimeMillis() - time1) + " ms");
    
    
    private static void usingStringBuilder(int n)
    {
        StringBuilder str = new StringBuilder();
        for(int i=0;i<n;i++)
            str.append("myBigString");    
    }
    
    private static void usingStringConcatenation(int n)
    {
        String str = "";
        for(int i=0;i<n;i++)
            str+="myBigString";
    }
    
  

E 'davvero un incubo se si utilizza concatenazione di stringhe per gran numero di stringhe.

usingStringConcatenation 29321 ms
usingStringBuilder 2 ms

Credo che dovremmo andare con StringBuilder accodare approccio. La ragione è

  1. La concatenazione String creerà una nuova stringa oggetto ogni volta (come stringa è oggetto immutabile), quindi creerà 3 oggetti.

  2. con stringa builder creato solo oggetto [StringBuilder è muttable] e l'ulteriore stringa viene aggiunta ad essa.

Per le stringhe semplici, come che io preferisco usare

"string".concat("string").concat("string");

Al fine, direi che il metodo preferito di costruire una stringa usa StringBuilder, String # concat (), quindi il sovraccarico operatore +. StringBuilder è un aumento significativo delle prestazioni quando si lavora stringhe grandi proprio come con l'operatore + è una forte diminuzione delle prestazioni (esponenziale forte diminuzione al crescere della dimensione della stringa). L'unico problema con l'utilizzo .concat () è che si può buttare NullPointerExceptions.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top