4

I frequently come across the task to create a String representation of a collection of objects.

example:

String[] collection = {"foo", "bar", "lorem", "dolar"};

The representation I want to create: "foo, bar, lorem, dolar".

Everytime I come across this task I wonder which is the cleanest most convinient way to achieve the desired result..

I know there are a lot of ways to get the desired representation but for example I always wondered, if there is any possibility to create the string by just using the for/each loop?

like so:

StringBuilder builder = new StringBuilder();

for (String tag : list) {
  builder.append(tag + ", ");

String representation = builder.toString();
// but now the String look like this: "foo, bar, lorem, dolar, " which nobody wants

Or is it best to just use the iterator if there is one, directly?

supposing list is a collection (that's how they kind of do it in the JDK):

Iterator<String> it = list.iterator();
while (it.hasNext()) {
  sb.append(it.next());
  if (!it.hasNext()) {
    break;
  }
  sb.append(", ");
}

One could of course index over the array with a traditional for-loop or do many other things.

Question

What is the easiest / best readable / safest way to convert a list of strings into the representation separating each element with a comma, and handle the edge case in the beginning or the end (meaning that there is no comma before the first element or after the last element) ?

Jan
  • 2,025
  • 17
  • 27
  • 2
    If you're using Java 8, look at StringJoiner. – Jon Skeet Aug 11 '15 at 10:43
  • Thanks @KevinEsche... I have really looked around but I did not find the question you were pointing out, and yes, that covers a lot of what I asked about. – Jan Aug 11 '15 at 10:46
  • @JonSkeet I can use Java 8, I will have a look at StringJoiner, never heard of it, thanks – Jan Aug 11 '15 at 10:47

8 Answers8

6

With Java 8, you can:

String listJoined = String.join(",", list);
Amila
  • 5,195
  • 1
  • 27
  • 46
1

Using Java8 use

String joined = Stream.of(collection)
                    //.map(Object::toString) //for non-String elements
                      .collect(Collectors.joining(","));

to get the desired result or the String.join as propagated above.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
col.panic
  • 2,944
  • 4
  • 25
  • 31
  • 1
    `map(o -> o.toString())` is unnecessary since we are already handing String elements, also `u + "," + t` is very inefficient because each time it hast to create new String which will be copy of `old one` plus `new part`. You should use StringBuilder/StringJoiner instead and append new part to it, or since we are using `stream` simply use `collect(Collectors.joining(delimiter))` instead of `reduce`. – Pshemo Aug 11 '15 at 12:22
1

I think the most readable one would be:

String[] collection = {"foo", "bar", "lorem", "dolar"};
String s = Arrays.asList(collection).toString();
System.out.println(s);

Output

[foo, bar, lorem, dolar]
Maulik Shah
  • 402
  • 1
  • 4
  • 18
0

You can try this way

String[] collection = {"foo", "bar", "lorem", "dolar"};    
StringBuilder sb=new StringBuilder();
for(String i:collection){
   sb.append(i);
   sb.append(",");
}
sb.replace(sb.lastIndexOf(","),sb.lastIndexOf(",")+1,"");
System.out.println(sb.toString());

Out put:

foo,bar,lorem,dolar

In Java 8 you can try as follows.

 String[] collection = {"foo", "bar", "lorem", "dolar"};   
 StringJoiner sj=new StringJoiner(",");
 for(String i:collection){
    sj.add(i);
 }
 System.out.println(sj.toString());
Ruchira Gayan Ranaweera
  • 34,993
  • 17
  • 75
  • 115
0

You may like to use Apache Commons's join

public static String join(Iterable iterable, char separator) Joins the elements of the provided Iterable into a single String containing the provided elements. No delimiter is added before or after the list. Null objects or empty strings within the iteration are represented by empty strings. See the examples here: join(Object[],char). Parameters: iterable - the Iterable providing the values to join together, may be null separator - the separator character to use Returns: the joined String, null if null iterator input

It is already implemented in a popular utils package and performs exactly what you are doing in your code.

As an alternate implementation, just for discussion, you may like to append to your string buffer the comma on every iteration but skip the final character when returning the string

Iterator<String> it = list.iterator();
while (it.hasNext()) {
  sb.append(it.next());
  sb.append(", ");
}
return sb.substring(0,sb.length()-1);
usr-local-ΕΨΗΕΛΩΝ
  • 26,101
  • 30
  • 154
  • 305
0

you can use the Arrays.asList function that turns your array into a List object.

The toString function applied on the list returns something like

stringCollection = "[foo, bar, lorem, dolar]"

Here you just need to remove the first and last characters '[' and ']' with the substring function.

result = "foo, bar, lorem, dolar"

//This is your String array
String[] collection = {"foo", "bar", "lorem", "dolar"};
//You convert it to a List and apply toString
String stringCollection = Arrays.asList(collection).toString(); 
//Remove the '[' and  ']' fromt the resulted String 
String result = stringCollection.substring(1, stringCollection.length()-1);
CriPstian
  • 129
  • 2
  • 8
0

using streams in java8:

String[] collection = {"foo", "bar", "lorem", "dolar"};    
String output = Arrays.asList(collection ).stream().collect(Collectors.joining(", "));
Alex
  • 409
  • 5
  • 12
0

Use Apache's commons lang : StringUtils.join(collection , ',');

Another similar question and answer here

Community
  • 1
  • 1
karim mohsen
  • 2,164
  • 1
  • 15
  • 19