1

I am attempting to add a comma separator to the String representation of a Java ArrayList but nothing seems to work, I am obviously missing something simple.

Sadly old Java 6 (running in a JSP):

ArrayList zones= new ArrayList();
zones.add(pageContext.getAttribute("zone"));

for(int i=0; i<zones.size(); i++)
out.println(zones.get(i));

// output is   CellA116 CellA116 CellA116 Reception Reception CellA11

StringBuffer stringBuffer = new StringBuffer();
for(int i=0; i<zones.size(); i++)
{
stringBuffer.append(zones.get(i));
stringBuffer.append(",");
}

out.println(stringBuffer.toString());

// output is   CellA116,CellA116,CellA116,Reception,Reception,CellA11,  (commas)

  %>     

</tr>
</c:forEach>

syntax wont work here (outside of loop)
out.println(stringBuffer.substring(0, stringBuffer.length() - 1));

I need to remove the final comma (as I eventually want to use the array in chart.js), appreciate any thoughts.

Ralph
  • 115
  • 1
  • 13
  • 3
    `zones.toString().replaceAll("[\\[\\]\\s]", "")`? [Demo](https://ideone.com/upkheP) – Lino May 03 '19 at 09:34
  • If you can use Java 8, take a look at this: https://ideone.com/43GQlC – lealceldeiro May 03 '19 at 09:42
  • See this answer which also addresses the JSp context: [Java: convert List to a String](https://stackoverflow.com/questions/1751844/java-convert-liststring-to-a-string/15837355#15837355) – Eritrean May 03 '19 at 09:58
  • Possible duplicate of [Java: convert List to a String](https://stackoverflow.com/questions/1751844/java-convert-liststring-to-a-string) – DaveyDaveDave May 03 '19 at 10:02

3 Answers3

2

Generally speaking, relying on a toString() method to do this is an easy way to inadvertently introduce bugs later on. If you change what concrete class is providing the collection (maybe to a Set instead of a List for example), your assumption that it starts and ends with square brackets might be untrue, and your output might change without you realising it.

I'd suggest that a more appropriate solution would be to iterate over the collection of Strings and add them to a StringBuilder.

So, it might look something like:

StringBuilder stringBuilder = new StringBuilder();
for(int i=0; i<strList.size(); i++)
{
    stringBuilder.append(strList.get(i));
    stringBuilder.append(",");
}

// Remove the last character from the StringBuilder to avoid a trailing comma.
String commaSeparatedList = stringBuilder.substring(0, stringBuilder.length() - 1);

out.println(commaSeparatedList);
DaveyDaveDave
  • 9,821
  • 11
  • 64
  • 77
  • I changed it to StringBuffer and that seems to work (commas included) but the substring attempt removes all the commas – Ralph May 03 '19 at 09:50
  • `StringBuffer` should be fine too - see the first line of the [`StringBuilder` docs](https://docs.oracle.com/javase/6/docs/api/java/lang/StringBuilder.html) for information about the difference. – DaveyDaveDave May 03 '19 at 09:54
  • Oh! You will need to have the `.substring` line outside the loop (i.e. after the loop has finished), if you have it inside the loop, that would remove the commas as you describe. – DaveyDaveDave May 03 '19 at 09:56
  • 1
    Thanks again, the loop is a jstl c:forEach loop so I have to fugure out how to do the substring outside of that loop – Ralph May 03 '19 at 10:24
  • original edited (perhaps I can 'transfer' the array to javascript and then strip the last comma there, though I have been trying to 'transfer' the java ArrayList to javascript (in the same jsp) for over a week now and this seems to be beyond me. – Ralph May 03 '19 at 10:32
  • It's a long time since I've done JSP, and I remember getting between Java-land and JS-land being difficult (although achievable) - probably worth a separate question here. As for the edit - I'm not sure I'm following - is the `for` loop part normal Java within `<% %>` tags, which themselves are wrapped with `` tags? Or have you only edited the question to show the end of the for loop (i.e. the ``)? – DaveyDaveDave May 03 '19 at 10:37
  • the forEach loop is large and is the output of a sql select first put into c:set variables which then end up in ArrayList zones, that part is working. 'transferring' java to javascript in the same jsp just confuses me but then I am a newbie. I appreciate your help, have been struggling with the basics for over a week. – Ralph May 03 '19 at 10:41
  • 1
    just some tips,in jsp forEach I guess there has a method to get the current count for the loop,if the count is not equal the size of the list,append comma. So the last comma will not show – 李振纲 May 03 '19 at 12:05
2

You can utilize a StringBuilder and a classic for loop to output a csv line from List<String>.

Have a look at this:

public static void main(String args[]) {
    List<String> zones = new ArrayList<String>();
    zones.add("CellA116");
    zones.add("CellA116");
    zones.add("CellA116");
    zones.add("Reception");
    zones.add("Reception");
    zones.add("CellA11");

    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < zones.size(); i++) {
        if (i < zones.size() - 1) {
            sb.append(zones.get(i)).append(";");
        } else {
            sb.append(zones.get(i));
        }
    }

    System.out.println(sb.toString());
}

The output will look like this:

CellA116;CellA116;CellA116;Reception;Reception;CellA11

If you want to have a method with a flexible separator char, then use something like this:

public static String toSeparatedString(List<String> values, char separator) {
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < values.size(); i++) {
        if (i < values.size() - 1) {
            sb.append(values.get(i)).append(separator);
        } else {
            sb.append(values.get(i));
        }
    }

    return sb.toString();
}
deHaar
  • 17,687
  • 10
  • 38
  • 51
  • Thanks but this if (i < values.size() - 1) causes an issue (either results in no output or strips all commas if already inserted) – Ralph May 03 '19 at 10:17
  • @Ralph this is for a `List` that has no commas inserted before but It will not strip out anything. How are you using it? The `if` statement just determines if the currently handled `String` is the last one and if it is, there will be no trailing separator character. That's the only purpose of it. – deHaar May 03 '19 at 10:22
-2

I dont see the need for another for loop to replace the [] and , zones.toString().replaceAll("[\[\]\s]", "") suggested by Lino works well.

Prabhu
  • 129
  • 1
  • 1
  • 9