【问题标题】:Join strings with different separators in Java在 Java 中连接具有不同分隔符的字符串
【发布时间】:2016-07-26 18:58:55
【问题描述】:

我有一个字符串列表,例如一周中的日子。我想用逗号加入他们,在最后一个元素之前加上“and”。例如:“我在周二、周三、周四周五有空”。

优雅的东西

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

不起作用。有没有一种优雅的方法可以使用 Guava 或类似的库?

谢谢

【问题讨论】:

  • 从上面的语句中获取结果,在最后一个分隔符上进行拆分并附加任何你想要的。我认为没有任何预定义的方法可用于您正在寻找的东西。
  • 这是一个很好的解决方案,但如果我不只使用日期,则可能不正确。如果我把它变成一个通用函数并且连接的元素有分隔符,我就有麻烦了......
  • 如果你想要通用函数,那么不要在你的连接条件中附加最后一个元素(将该元素从你传递给加入的列表中取出)并编写你自己的方法来附加最后一个,这将足以处理任何情况。您可以通过创建一个具有分隔第一组元素和第二组元素的索引的单个方法以及用户定义的连接“文本”来使其更通用。使用两个连接并附加两个连接的结果。

标签: java guava joiner


【解决方案1】:

没有直接的解决方案,但你可以考虑我的:

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() &lt; 2)可以由 if 语句处理。

【讨论】:

  • 谢谢,没关系,列表还是数组,这是我一直在思考的一个方向……
  • P.S.烦人的事情是我必须处理边缘情况。例如。您的代码将在空列表上引发异常。这不是很多工作,但我希望 Guava 有一个单行解决方案..
【解决方案2】:

考虑到您“目前对 Java 8 不友好”(您可能是指 lambda 和流),使用 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&lt;? extends CharSequence&gt;)

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 switch solution

【讨论】:

  • 不幸的是,StringJoiner 也仅在 Java 8+ 中可用。
  • @Xaerxess:我知道,这就是为什么我说“你可能是指 lambda 和流”。我认为(并且仍然认为)OP 正在谈论它们附带的不同语法/编码风格。当然,如果他根本不想(或不能)使用 JDK 8,那不是一个有效的解决方案。
【解决方案3】:

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

它处理除了 strings 中的 null 元素之外的所有边缘情况 - 如果您想处理它们而不抛出 NPE,请将 .useForNull(stringForNull) 添加到您的加入者。

【讨论】:

    【解决方案4】:

    感谢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")));
    

    提供: 一二三四

    【讨论】:

    • 你可以使用replaceFirst("((?s:.*)_,_", "$1 and")
    猜你喜欢
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 2018-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多