Idioma preferido para ingressar em uma coleção de strings em Java

Dada uma coleção de strings, como você as uniria em Java simples, sem usar uma biblioteca externa?

Dadas estas variables:

Collection data = Arrays.asList("Snap", "Crackle", "Pop"); String separator = ", "; String joined; // let's create this, shall we? 

É assim que eu faria em Goiaba :

 joined = Joiner.on(separator).join(data); 

E no Apache Commons / Lang :

 joined = StringUtils.join(data, separator); 

Mas na planície Java, não há realmente nenhuma maneira melhor do que isso?

 StringBuilder sb = new StringBuilder(); for(String item : data){ if(sb.length()>0)sb.append(separator); sb.append(item); } joined = sb.toString(); 

Eu diria que a melhor maneira de fazer isso (se pelo melhor você não quer dizer “mais conciso”) sem usar Guava é usar a técnica que o Guava usa internamente, que para o seu exemplo seria algo como isto:

 Iterator iter = data.iterator(); StringBuilder sb = new StringBuilder(); if (iter.hasNext()) { sb.append(iter.next()); while (iter.hasNext()) { sb.append(separator).append(iter.next()); } } String joined = sb.toString(); 

Isso não precisa fazer uma verificação booleana durante a iteração e não precisa fazer nenhum pós-processamento da string.

Pode ser em vez de chamar sb.length () de novo e de novo em um loop, eu tenho um pouco modificado.

 StringBuilder sb = new StringBuilder(); String separator = ""; for(String item : data){ sb.append(separator); separator=","; sb.append(item); } joined = sb.toString(); 

Java 8+

joined = String.join(separator, data);

Java 7 e abaixo

 StringBuilder sb = new StringBuilder(); boolean first = true; for(String item : data){ if(!first || (first = false)) sb.append(separator); sb.append(item); } joined = sb.toString(); 

No Java 8:

 String.join (separator, data) 

Intenções diferentes:

Para ferramentas de terceiros, como o Joiner de Guava, que não é rápido, mas muito flexível . Existem muitos methods de opção para personalizar o comportamento de junit, como skipNulls() .

Java simples é rápido , mas você precisa escrever algumas linhas de códigos por conta própria.

Os coletores podem se juntar ao Streams, o que é muito útil se você quiser filter ou map seus dados.

 String joined = Stream.of("Snap", "Crackle", "Pop") .map(String::toUpperCase) .collect(Collectors.joining(", ")); 

Para obter um stream de uma coleção, chame stream() nele:

 Arrays.asList("Snap", "Crackle", "Pop").stream() 

Sua proposição é uma solução possível, outra comum é:

 for (String item: data) { sb.append(item) sb.append(separator); } String joined = sb.substring(0, sb.length() - separator.length())