0

如何使用 Java 8 Streams 减少或收集以逗号分隔并仅将“and”前缀到最后一个元素的字符串列表?

例如。

List<String> ls = Arrays.asList("tom","terry","john","kevin","steve");

String result = ls.stream().map(String::toString)
                .collect(Collectors.joining(", "));

System.out.println(result);

此语句打印 => tom, terry, john, kevin, steve。但我想将列表打印为汤姆、特里、约翰、凯文和史蒂夫。

4

3 回答 3

2

两种解决方案。

笨拙,实际上采用子列表:

    String result = ls.stream()
            .limit(ls.size() - 1)
            .collect(Collectors.joining(", ")) + " and " + ls.get(ls.size() - 1);

使用类转移一个地方:

    class SbS {
        StringBuilder sb = new StringBuilder();
        String s = "";

        @Override
        public String toString() {
            return sb + (s.empty() ? "" : " and " + s);
        }
    }
    result = ls.stream()
            .collect(SbS::new,
                (a, s) -> {
                    a.sb.append(a.sb.length() == 0 ? "" : ", ").append(a.s); a.s = s;
                },
                (a1, a2) -> {}).toString();

注意:类定义应该放在方法内部,就像上面一样。否则static将需要。的 lambda(a, s)可能是 SbS 中的一种方法。对并行性的支持留给读者作为练习(a1, a1)

于 2016-08-10T12:33:31.273 回答
1

流不会使这更容易。你也可以使用String::replaceAll

String input = "tom, terry, john, kevin, steve";
String result = input.replaceAll(", (\\w+)$", " and $1");

System.out.println(result);

输出:

tom, terry, john, kevin and steve
于 2016-08-09T23:13:41.877 回答
0

Stream API 没有提供实现这一点的标准方法。我的扩展标准 Stream API 的StreamEx库有一个mapLast在这里很有帮助的方法。它只允许映射最后一个流元素,而其他所有内容都保持原样:

System.out.println(StreamEx.of(ls).mapLast("and "::concat).joining(", "));

结果如下:

tom, terry, john, kevin, and steve

请注意,它在“and”之前添加了一个逗号,这是可以的(请参阅Oxford Comma)。如果您不喜欢它(或实际上使用禁止此类标点符号的另一种语言),则可以以稍长的方式实现:

StreamEx.of(ls)
        .mapLastOrElse(", "::concat, " and "::concat)
        .joining().substring(", ".length());
于 2016-08-11T05:00:58.177 回答