I run into this case a lot of times when doing simple text processing and print statements where I am looping over a collection and I want to special case the last element (for example every normal element will be comma separated except for the last case).
Is there some best practice idiom or elegant form that doesn't require duplicating code or shoving in an if, else in the loop.
For example I have a list of strings that I want to print in a comma separated list. (the do while solution already assumes the list has 2 or more elements otherwise it'd be just as bad as the more correct for loop with conditional).
e.g. List = ("dog", "cat", "bat")
I want to print "[dog, cat, bat]"
I present 2 methods the
For loop with conditional
public static String forLoopConditional(String[] items) { String itemOutput = "["; for (int i = 0; i < items.length; i++) { // Check if we're not at the last element if (i < (items.length - 1)) { itemOutput += items[i] + ", "; } else { // last element itemOutput += items[i]; } } itemOutput += "]"; return itemOutput; }
do while loop priming the loop
public static String doWhileLoopPrime(String[] items) { String itemOutput = "["; int i = 0; itemOutput += items[i++]; if (i < (items.length)) { do { itemOutput += ", " + items[i++]; } while (i < items.length); } itemOutput += "]"; return itemOutput; }
Tester class:
public static void main(String[] args) { String[] items = { "dog", "cat", "bat" };
}System.out.println(forLoopConditional(items)); System.out.println(doWhileLoopPrime(items));
In the Java AbstractCollection class it has the following implementation (a little verbose because it contains all edge case error checking, but not bad).
public String toString() {
Iterator<E> i = iterator();
if (! i.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = i.next();
sb.append(e == this ? "(this Collection)" : e);
if (! i.hasNext())
return sb.append(']').toString();
sb.append(", ");
}
}