I have a list of strings, e.g. days of the week. And I'd like to join them on comma, with "and" before the last element. E.g: "I'm available on Tue, Wed, Thu and Fri".
Something elegant like
Joiner.on(", ").join(days)
Does not work. Is there an elegant way to do it with Guava or similar library?
Thanks
There is no straightforward solution, but you may consider mine:
final String COMMA = ", ", AND = " and ";
List<String> list = Arrays.asList("Tue", "Wed", "Thu", "Fri");
int last = list.size() - 1;
Joiner.on(AND).join(
list.stream().limit(last).collect(joining(COMMA)),
list.get(last)); // Tue, Wed, Thu and Fri
The another shorter way is:
list.stream().limit(last).collect(joining(COMMA, "", AND))
.concat(list.get(last));
These methods perfectly work for 2+ days.
Edge cases (list == null || list.isEmpty()
and list.size() < 2
) may be handled by the if
statements.
Considering you're "not Java 8 friendly at this moment" (you probably mean lambdas and streams), how about using StringJoiner
:
public static String join(List<String> parts, String delimiter, String lastDelimiter) {
StringJoiner joiner = new StringJoiner(delimiter, "", lastDelimiter);
for (int i = 0; i < parts.size() - 1; i++) {
joiner.add(parts.get(i));
}
return joiner.toString() + parts.get(parts.size() - 1);
}
However, doing the same with streams:
public static String join(List<String> parts, String delimiter, String lastDelimiter) {
return parts.stream()
.limit(parts.size() - 1)
.collect(Collectors.joining(delimiter, "", lastDelimiter))
.concat(parts.get(parts.size() - 1));
}
EDIT: Just found String#join(CharSequence, Iterable<? extends CharSequence>)
:
public static String join(List<String> parts, String delimiter, String lastDelimiter) {
return String.join(delimiter, parts.subList(0, parts.size() - 1))
+ lastDelimiter + parts.get(parts.size() - 1);
}
In order to handle corner cases I'd go for Xaerxess switch solution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With