4

曜日などの文字列のリストがあります。そして、最後の要素の前に「and」を付けて、カンマで結合したいと思います。例: 「火、水、木金は対応可能です」。

みたいなエレガントなもの

Joiner.on(", ").join(days)

動作しません。Guava または同様のライブラリでそれを行うエレガントな方法はありますか?

ありがとう

4

4 に答える 4

4

簡単な解決策はありませんが、私のものを検討してください:

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

別の短い方法は次のとおりです。

list.stream().limit(last).collect(joining(COMMA, "", AND))
    .concat(list.get(last));

これらの方法は、2 日以上完全に機能します。

エッジ ケース (list == null || list.isEmpty()およびlist.size() < 2) は、ifステートメントによって処理される場合があります。

于 2016-07-26T19:09:08.073 に答える
3

「現時点ではJava 8に対応していない」(おそらくラムダとストリームを意味する)ことを考えると、次を使用するのはどうですか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);
}

ただし、ストリームでも同じことを行います。

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));
}

編集:ちょうど見つかった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);
}

まれなケースを処理するために、Xaerxess スイッチ ソリューションを使用します。

于 2016-07-26T21:40:07.063 に答える
2

Guava を使用した Java 6/7 互換ソリューション:

static String join(List<String> strings, String separator, String lastSeparator)
{
    checkNotNull(strings);
    switch (strings.size()) {
        case 0:
            return "";
        case 1:
            return strings.get(0);
        default:
            return Joiner.on(separator).join(strings.subList(0, strings.size() - 1))
                    + lastSeparator + strings.get(strings.size() - 1);
    }
}

または、受け入れたい場合Iterable(および/またはより多くのグアバのものを使用する場合):

static String join(Iterable<String> strings, String separator, String lastSeparator)
{
    checkNotNull(strings);
    int size = Iterables.size(strings);
    switch (size) {
        case 0:
            return "";
        case 1:
            return strings.iterator().next();
        default:
            return Joiner.on(separator).join(Iterables.limit(strings, size - 1))
                    + lastSeparator + Iterables.getLast(strings);
    }
}

null要素を除くすべてのエッジケースをstrings処理します-それらを処理し、NPEをスローしない場合は.useForNull(stringForNull)、ジョイナーに追加します。

于 2016-07-27T09:17:33.887 に答える
1

Java には replaceFirst があり、replaceLast がなく、「_,_」が要素/パーツのいずれにも表示されないと仮定して、次の関数をハックしました。

public static String join(Iterable<?> parts) {
    String reverse = new StringBuilder(Joiner.on("_,_").join(parts)).reverse().toString();
    reverse = reverse.replaceFirst("_,_", " dna ").replaceAll("_,_", " ,");
    return new StringBuilder(reverse).reverse().toString();
}

その後:

System.out.println(join(Arrays.asList("One", "Two", "Three", "Four")));

ギブス: 1、2、3、4

于 2016-07-26T19:50:09.340 に答える