2014-12-17 9 views
29

Recentemente mi sono imbattuto in una classe Java 8 StringJoiner che aggiunge la stringa utilizzando i delimitatori e aggiunge prefisso e suffisso, ma non riesco a capire la necessità di questa classe poiché utilizza anche StringBuilder nel backend ed esegue anche molto semplice operazione di accodamento delle stringhe.Perché StringJoiner quando abbiamo già StringBuilder?

Mi manca qualcosa non capendo il vero scopo di questa classe?

+2

Essendo semplice da implementare non preclude l'utilità quando viene eseguito come classe a sé stante. Soprattutto se si considera * la frequenza con cui * i programmatori di applicazioni dovevano farlo a mano (o tramite una libreria di terze parti). – Holger

risposta

12

Gli esempi su StringJoiner Javadoc sono molto bravi a coprire questo. L'intero punto è quello di astrarre la scelta del separatore dall'atto di aggiungere voci. per esempio. puoi creare un falegname, specificare il separatore da usare e passarlo a una libreria per fare l'aggiunta di elementi o viceversa.

la stringa "[George: di Sally: Fred]" può essere costruito come segue:

StringJoiner sj = new StringJoiner(":", "[", "]"); 
sj.add("George").add("Sally").add("Fred"); 
String desiredString = sj.toString(); 

Uno StringJoiner può essere impiegato per creare output formattato da un flusso utilizzando Collectors.joining (CharSequence). Ad esempio:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4); 
String commaSeparatedNumbers = numbers.stream() 
    .map(i -> i.toString()) 
    .collect(Collectors.joining(", ")); 
+2

Peter, hai fatto qualche benchmark sulle prestazioni di StringBuilder rispetto a StringJoiner? Quale preferiresti da questo punto di vista? –

+1

@Simeon Userò String joiner se voglio un separatore implicito tra ogni cosa che aggiungo e un generatore di stringhe se non lo è. Non si tratta di prestazioni, ma rendendo più chiara l'azione desiderata. –

7

StringJoiner è una sorta di un collettore , anche se non implementa l'interfaccia Collector. Si comporta come tale. Oltre a poter passare delimitatore, prefisso e suffisso, è possibile utilizzare StringJoiner per creare output formattato dainvocando Collectors.joining(CharSequence).

Ciò è particolarmente utile quando si lavora con flussi paralleli, perché ad un certo punto i lotti che vengono processo in parallelo dovranno essere unita e questo è dove il StringJoiner avviene.

+6

Non esattamente.È un componente di utilità di basso livello adatto per l'uso da un Collector (joining() lo usa di fatto), ma anche adatto al di fuori del mondo degli Stream. Le persone scrivono questo tipo di loop tutto il tempo. –

+1

Grazie, signor Goetz per il chiarimento. –

10

Può semplificare il codice, in alcuni casi di utilizzo:

List<String> list = // ...; 

// with StringBuilder 
StringBuilder builder = new StringBuilder(); 
builder.append("["); 
if (!list.isEmpty()) { 
    builder.append(list.get(0)); 
    for (int i = 1, n = list.size(); i < n; i++) { 
     builder.append(",").append(list.get(i)); 
    } 
} 
builder.append("]"); 

// with StringJoiner 
StringJoiner joiner = new StringJoiner(",", "[", "]"); 
for (String element : list) { 
    joiner.add(element); 
} 
49

StringJoiner è molto utile, quando è necessario unire le stringhe in un Stream.

Per fare un esempio, se si dispone a seguire lista di stringhe:

final List<String> strings = Arrays.asList("Foo", "Bar", "Baz"); 

è molto più semplice da usare

final String collectJoin = strings.stream().collect(Collectors.joining(", ")); 

come sarebbe con un StringBuilder:

final String collectBuilder = 
    strings.stream().collect(Collector.of(StringBuilder::new, 
     (stringBuilder, str) -> stringBuilder.append(str).append(", "), 
     StringBuilder::append, 
     StringBuilder::toString)); 
+1

Si noti che questi due esempi non sono uguali! Il primo genera la stringa '" foo, Bar, Baz "', e il secondo genera '" foo, Bar, Baz, "'. –

+3

@PaulWagland Sì, questa è la bellezza in più del '.joining'. Di solito, * non * non ha bisogno dell'ultima virgola ... – Koshinae

+2

@Koshinae è totalmente d'accordo, e ha stabilito che nel caso di streaming rende ancora più complicata la già complicata affermazione! –

Problemi correlati