小编典典

连接具有不同最后定界符的字符串

java

使用stream.collect(Collectors.joining(", "))I,可以轻松地连接流中所有用逗号分隔的字符串。可能的结果是"a, b, c"。但是,如果我希望最后一个定界符不同,该怎么办。例如," and "使我得到"a, b and c"结果。有一个简单的解决方案吗?


阅读 219

收藏
2020-11-16

共1个答案

小编典典

如果它们已经在列表中,则不需要流。只需加入除最后一个元素以外的所有元素的子列表,并连接另一个定界符和最后一个元素:

int last = list.size() - 1;
String joined = String.join(" and ",
                    String.join(", ", list.subList(0, last)),
                    list.get(last));

这是使用上述功能的版本 Collectors.collectingAndThen:

stream.collect(Collectors.collectingAndThen(Collectors.toList(),
    joiningLastDelimiter(", ", " and ")));

public static Function<List<String>, String> joiningLastDelimiter(
        String delimiter, String lastDelimiter) {
    return list -> {
                int last = list.size() - 1;
                if (last < 1) return String.join(delimiter, list);
                return String.join(lastDelimiter,
                    String.join(delimiter, list.subList(0, last)),
                    list.get(last));
            };
}

此版本还可以处理流为空或只有一个值的情况。感谢Holger和Andreas的建议,这些建议极大地改善了此解决方案。

我曾在评论中建议,可以使用", "", and"作为定界符来完成牛津逗号,但是"a, and b"对于两个元素而言,这会产生不正确的结果,因此,仅出于娱乐目的,这是正确执行牛津逗号的一个:

stream.collect(Collectors.collectingAndThen(Collectors.toList(),
    joiningOxfordComma()));

public static Function<List<String>, String> joiningOxfordComma() {
    return list -> {
                int last = list.size() - 1;
                if (last < 1) return String.join("", list);
                if (last == 1) return String.join(" and ", list);
                return String.join(", and ",
                    String.join(", ", list.subList(0, last)),
                    list.get(last));
            };
}
2020-11-16