Java 使用不同的最后定界符连接字符串

Java 使用不同的最后定界符连接字符串,java,string,java-8,java-stream,Java,String,Java 8,Java Stream,使用stream.collect(Collectors.joining(“,”)我可以轻松地连接流中由逗号分隔的所有字符串。可能的结果是“A、b、c”。但是,如果我希望最后一个分隔符不同,该怎么办呢。例如,“和”,这样我就得到了“a,b和c”。有一个简单的解决方案吗?首先尝试使用stream.collect(收集器.joining(“and”))连接最后两个字符串。 然后将所有剩余字符串和这个新字符串与您在问题中使用的代码连接起来:stream.collect(Collectors.joinin

使用
stream.collect(Collectors.joining(“,”)
我可以轻松地连接流中由逗号分隔的所有字符串。可能的结果是
“A、b、c”
。但是,如果我希望最后一个分隔符不同,该怎么办呢。例如,
“和”
,这样我就得到了
“a,b和c”
。有一个简单的解决方案吗?

首先尝试使用
stream.collect(收集器.joining(“and”))连接最后两个字符串。


然后将所有剩余字符串和这个新字符串与您在问题中使用的代码连接起来:
stream.collect(Collectors.joining(“,”)
如果它们已经在列表中,则不需要流;只需将除最后一个元素外的所有元素的子列表与另一个分隔符和最后一个元素连接起来:

int last = list.size() - 1;
String joined = String.join(" and ",
                    String.join(", ", list.subList(0, last)),
                    list.get(last));
下面是一个使用
收集器执行上述操作的版本。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));
            };
}
如果您对
“a、b和c”
没有问题,那么可以使用my library的方法,该方法通过附加操作扩展标准流API:

String result = StreamEx.of("a", "b", "c")
                        .mapLast("and "::concat)
                        .joining(", "); // "a, b, and c"
mapLast
方法将给定的映射应用于最后一个流元素,其他元素保持不变。我甚至有类似的解决方案。

如果您正在寻找旧的Java解决方案,那么使用它会很容易

    List<String> values = Arrays.asList("a", "b", "c");
    String output = Joiner.on(",").join(values);
    output = output.substring(0, output.lastIndexOf(","))+" and "+values.get(values.size()-1);
    System.out.println(output);//a,b and c
List values=Arrays.asList(“a”、“b”、“c”);
字符串输出=Joiner.on(“,”).join(值);
output=output.substring(0,output.lastIndexOf(“,”)+”和“+values.get(values.size()-1));
系统输出打印项次(输出)//a、 b和c
列表名称=数组;
int length=names.size();
字符串结果=IntStream.range(0,长度-1).mapToObj(i->{
如果(i==长度-2){
返回names.get(i)+“和”+names.get(长度-1);
}否则{
返回名称。获取(i);
}
}).collect(收集器。连接(“,”);

这不是Streams API解决方案,但速度非常快。享受吧

public static final <E> String join(
    Iterable<E> objects, String separator, String lastSeparator) 
{
    Objects.requireNonNull(objects);

    final String sep = separator == null ? "" : separator;
    final String lastSep = lastSeparator == null ? sep : lastSeparator;

    final StringBuilder builder = new StringBuilder();

    final Iterator<E> iterator = objects.iterator();
    while (iterator.hasNext()) {
        final E next = iterator.next();
        if (builder.length() > 0) {
            if (iterator.hasNext()) {
                builder.append(sep);
            }
            else {
                builder.append(lastSep);
            }
        }
        builder.append(next);
    }

    return builder.toString();
}
公共静态最终字符串联接(
Iterable对象、字符串分隔符、字符串分隔符)
{
对象。requirennoull(对象);
最后一个字符串sep=separator==null?“:分隔符;
最后一个字符串lastSep=lastSeparator==null?sep:lastSeparator;
最终StringBuilder=新StringBuilder();
final Iterator Iterator=objects.Iterator();
while(iterator.hasNext()){
final E next=iterator.next();
如果(builder.length()>0){
if(iterator.hasNext()){
建筑商追加(sep);
}
否则{
附加(最后一个九月);
}
}
builder.append(下一步);
}
返回builder.toString();
}

老实说,没有<代码>收集器。加入使用了一些非常笨拙的技巧,当你尝试这样做时,这些技巧会完全崩溃。实现你自己的。至于“容易”,这是一个技巧和观点的问题。@Andreas有可能实现这样一个收集器吗?收集器如何知道何时使用特殊分隔符?@erickson如果需要牛津逗号,请将分隔符指定为“
”、“
”和“
”。(我也喜欢它。)事实上,这不太管用,但我已经在我的答案中添加了一个牛津逗号变体。此外,我将其粘贴到Eclipse中,并得到一个编译错误,可以通过显式地给出以下类型来修复:
Collector.of(
Hmm,
javac
没有给我一个编译错误,但是我可以添加显式类型。Eclipse的哪个版本?因为这里唯一相关的函数是finisher,所以你可以简单地使用
Collectors.collectingand(Collectors.toList(),list->{…})
。顺便说一下,你也可以使用
String.join(用于return语句的lastdimiter,String.join(delimiter,list.subList(0,last)),list.get(last))
。这不是OP想要的答案,但如果您喜欢牛津逗号,这个答案在语法上是“more”正确的。谢谢Tagir。
    List<String> values = Arrays.asList("a", "b", "c");
    String output = Joiner.on(",").join(values);
    output = output.substring(0, output.lastIndexOf(","))+" and "+values.get(values.size()-1);
    System.out.println(output);//a,b and c
    List<String> names = Arrays.asList("Thomas", "Pierre", "Yussef", "Rick");
    int length = names.size();
    String result = IntStream.range(0, length - 1).mapToObj(i -> {
        if (i == length - 2) {
            return names.get(i) + " and " + names.get(length - 1);
        } else {
            return names.get(i);
        }
    }).collect(Collectors.joining(", "));
public static final <E> String join(
    Iterable<E> objects, String separator, String lastSeparator) 
{
    Objects.requireNonNull(objects);

    final String sep = separator == null ? "" : separator;
    final String lastSep = lastSeparator == null ? sep : lastSeparator;

    final StringBuilder builder = new StringBuilder();

    final Iterator<E> iterator = objects.iterator();
    while (iterator.hasNext()) {
        final E next = iterator.next();
        if (builder.length() > 0) {
            if (iterator.hasNext()) {
                builder.append(sep);
            }
            else {
                builder.append(lastSep);
            }
        }
        builder.append(next);
    }

    return builder.toString();
}