4

I'm iterating through a list of list of strings. I need to print each list in comma separated format except the last element. This is my code.

for(Iterator itr = list.iterator(); itr.hasNext();){
    List<String> l = (List<String>) itr.next();
    for(Iterator it = l.iterator(); it.hasNext();){
       System.out.print(it.next() + " ");
    }
    System.out.println();
}

This prints something like

listen, silent, tinsel,

How do I format the print logic to remove the comma after the last element. I can do that on for i loop checking the value of i against the last index, but wish to know how to do it with an Iterator in Java.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
Zeus
  • 2,213
  • 8
  • 28
  • 45
  • Why do you want to use iterator? Use stream api and `.collect(joining(","))` – Jaroslaw Pawlak Feb 21 '16 at 18:59
  • Ok I've never used the stream API, dont know how to do that. Will check it out. – Zeus Feb 21 '16 at 18:59
  • "*I need to print each list in comma separated format except the last element*" so if your lists are `[[a,b][c,d,e]]` would you like to print `a,b[lineSeparator]c,d,e` or `a,b,c,d,e`? – Pshemo Feb 21 '16 at 19:05
  • 2
    For the record, even if the answers you got are more elegant than what you have, you can just test if the iterator has a next element after calling next(). If it doesn't have a next element, then don't print the trailing comma. – JB Nizet Feb 21 '16 at 19:09

3 Answers3

5

Using Java 8, you don't to write any loop, you can just use String.join(delimiter, elements):

Returns a new String composed of copies of the CharSequence elements joined together with a copy of the specified delimiter.

A sample code would be:

for(Iterator<List<String>> itr = list.iterator(); itr.hasNext();){
    List<String> l = itr.next();
    String str = String.join(", ", l);
    System.out.println(str);
}

With such code, you don't need to worry about removing the last delimiter.

Tunaki
  • 132,869
  • 46
  • 340
  • 423
3

As far as I can see you have List<List<String>>. This is how it will look like with Java 8 stream api:

List<List<String>> list = Arrays.asList("a", "b", "c", "d", "e", "f", "g", "h");
String result = list.stream()
        .flatMap(innerList -> innerList.stream())
        .collect(joining(","));

flatMap takes all inner lists and creates a single stream of Strings by just concatenating the lists. collect(joining(",")) takes all the elements from this single stream and creates a String where values are separated by ",".

This will give you output like:

a,b,c,d,e,g,h

If you want each inner list on a separate line, try this one:

String result = list.stream()
        .map(innerList -> innerList.stream().collect(joining(",")))
        .collect(joining("\n"));

This will give you output like:

a,b,c
d,e
g,h
Jaroslaw Pawlak
  • 5,538
  • 7
  • 30
  • 57
  • We don't strictly know for sure that the OP has an `List>` that's why I kept the `Iterator` approach OP used. But the answer is still valid nonetheless. – Tunaki Feb 21 '16 at 19:09
  • @Tunaki Good idea. We can however convert iterator to stream in such case. I've made that assumption based on `list.iterator()` in the outer loop. – Jaroslaw Pawlak Feb 21 '16 at 19:10
2

Here is a general trick that can help with delimiters. Turn the issue around. Rather than appending the delimiter to all except the last string, print it in front of all except the first string. It is often easier to make special things happen for the first iteration. Here is one way to use this idea:

import java.util.Arrays;
import java.util.List;

public class Test {
  public static void main(String[] args) {
    List<String> list = Arrays.asList(new String[]{"aa", "bb", "cc"});
    String delim = "";
    for(String s : list){
      System.out.print(delim);
      delim = ", ";
      System.out.print(s);
    }
    System.out.println();
  }
}

prints

aa, bb, cc
Patricia Shanahan
  • 25,849
  • 4
  • 38
  • 75