当我在一个Java应用程序中工作时,我最近需要组装一个以逗号分隔的值列表,以传递给另一个web服务,而不知道预先会有多少个元素。我能想到的最好的是这样的:

public String appendWithDelimiter( String original, String addition, String delimiter ) {
    if ( original.equals( "" ) ) {
        return addition;
    } else {
        return original + delimiter + addition;
    }
}

String parameterString = "";
if ( condition ) parameterString = appendWithDelimiter( parameterString, "elementName", "," );
if ( anotherCondition ) parameterString = appendWithDelimiter( parameterString, "anotherElementName", "," );

我意识到这不是特别有效,因为到处都在创建字符串,但我追求的是清晰而不是优化。

在Ruby中,我可以这样做,这感觉要优雅得多:

parameterArray = [];
parameterArray << "elementName" if condition;
parameterArray << "anotherElementName" if anotherCondition;
parameterString = parameterArray.join(",");

但是由于Java缺少join命令,我找不到任何等价的命令。

那么,在Java中最好的方法是什么呢?


当前回答

Java 8原生类型

List<Integer> example;
example.add(1);
example.add(2);
example.add(3);
...
example.stream().collect(Collectors.joining(","));

Java 8自定义对象:

List<Person> person;
...
person.stream().map(Person::getAge).collect(Collectors.joining(","));

其他回答

如果你想在对象属性的列表中应用逗号。这是我发现最有用的方法。

这里getName()是一个类的字符串属性,我一直试图添加“,”。

字符串消息= listName.stream()。map(list -> list. getname ()).collect(collections . getname ())加入(","));

为什么不编写自己的join()方法呢?它将接受String和分隔符String的参数集合。在方法中遍历集合并在StringBuffer中构建结果。

使用Dollar就像输入一样简单:

String joined = $(aCollection).join(",");

注意:它也适用于数组和其他数据类型

实现

在内部,它使用了一个非常巧妙的技巧:

@Override
public String join(String separator) {
    Separator sep = new Separator(separator);
    StringBuilder sb = new StringBuilder();

    for (T item : iterable) {
        sb.append(sep).append(item);
    }

    return sb.toString();
}

Separator类只在第一次调用时返回空String,然后返回分隔符:

class Separator {

    private final String separator;
    private boolean wasCalled;

    public Separator(String separator) {
        this.separator = separator;
        this.wasCalled = false;
    }

    @Override
    public String toString() {
        if (!wasCalled) {
            wasCalled = true;
            return "";
        } else {
            return separator;
        }
    }
}

在Java 8中,你可以这样做:

list.stream().map(Object::toString)
        .collect(Collectors.joining(delimiter));

如果列表有空值,你可以使用:

list.stream().map(String::valueOf)
        .collect(Collectors.joining(delimiter))

它还支持前缀和后缀:

list.stream().map(String::valueOf)
        .collect(Collectors.joining(delimiter, prefix, suffix));

您可以泛化它,但正如您所说,Java中没有连接。

这样可能效果更好。

public static String join(Iterable<? extends CharSequence> s, String delimiter) {
    Iterator<? extends CharSequence> iter = s.iterator();
    if (!iter.hasNext()) return "";
    StringBuilder buffer = new StringBuilder(iter.next());
    while (iter.hasNext()) buffer.append(delimiter).append(iter.next());
    return buffer.toString();
}