Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Join strings with different separators in Java

Tags:

java

guava

joiner

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

like image 385
Scott Mayers Avatar asked Dec 24 '22 03:12

Scott Mayers


2 Answers

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.

like image 52
Andrew Tobilko Avatar answered Dec 28 '22 08:12

Andrew Tobilko


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.

like image 30
beatngu13 Avatar answered Dec 28 '22 07:12

beatngu13