JavaScript有Array.join()

js>["Bill","Bob","Steve"].join(" and ")
Bill and Bob and Steve

Java有这样的东西吗?我知道我可以用StringBuilder自己拼凑一些东西:

static public String join(List<String> list, String conjunction)
{
   StringBuilder sb = new StringBuilder();
   boolean first = true;
   for (String item : list)
   {
      if (first)
         first = false;
      else
         sb.append(conjunction);
      sb.append(item);
   }
   return sb.toString();
}

. .但是如果像这样的东西已经是JDK的一部分,那么这样做就没有意义了。


当前回答

Java 8确实带来了

Collectors.joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)

方法,通过对空值使用前缀+后缀,该方法为nullsafe。

它可以以以下方式使用:

String s = stringList.stream().collect(Collectors.joining(" and ", "prefix_", "_suffix"))

收藏家。join (CharSequence delimiter)方法只是在内部调用joining(delimiter, "", "")。

其他回答

谷歌的Guava API也有.join(),尽管(从其他回复中应该很明显),Apache Commons在这里几乎是标准的。

我写了这个(我用它来bean和利用toString,所以不要写Collection<String>):

public static String join(Collection<?> col, String delim) {
    StringBuilder sb = new StringBuilder();
    Iterator<?> iter = col.iterator();
    if (iter.hasNext())
        sb.append(iter.next().toString());
    while (iter.hasNext()) {
        sb.append(delim);
        sb.append(iter.next().toString());
    }
    return sb.toString();
}

但是JSP不支持Collection,所以对于TLD我写了:

public static String join(List<?> list, String delim) {
    int len = list.size();
    if (len == 0)
        return "";
    StringBuilder sb = new StringBuilder(list.get(0).toString());
    for (int i = 1; i < len; i++) {
        sb.append(delim);
        sb.append(list.get(i).toString());
    }
    return sb.toString();
}

并放入。tld文件:

<?xml version="1.0" encoding="UTF-8"?>
<taglib version="2.1" xmlns="http://java.sun.com/xml/ns/javaee"
    <function>
        <name>join</name>
        <function-class>com.core.util.ReportUtil</function-class>
        <function-signature>java.lang.String join(java.util.List, java.lang.String)</function-signature>
    </function>
</taglib>

并在JSP文件中使用它:

<%@taglib prefix="funnyFmt" uri="tag:com.core.util,2013:funnyFmt"%>
${funnyFmt:join(books, ", ")}

不,在标准Java API中没有这样方便的方法。

毫不奇怪,Apache Commons在它们的StringUtils类中提供了这样一个东西,以防您不想自己编写它。

String.join

在Java 8中,你不需要任何第三方库就可以做到这一点。

如果你想加入一个字符串集合,你可以使用String.join()方法:

List<String> list = Arrays.asList("foo", "bar", "baz");
String joined = String.join(" and ", list); // "foo and bar and baz"

Collectors.joining

如果你有一个非String类型的Collection,你可以使用Stream API来连接Collector:

List<Person> list = Arrays.asList(
  new Person("John", "Smith"),
  new Person("Anna", "Martinez"),
  new Person("Paul", "Watson ")
);

String joinedFirstNames = list.stream()
  .map(Person::getFirstName)
  .collect(Collectors.joining(", ")); // "John, Anna, Paul"

StringJoiner类可能也很有用。

EDIT

我还注意到toString()底层实现问题,以及包含分隔符的元素,但我认为我是偏执狂。

鉴于我对此有两点看法,我将我的答案改为:

static String join( List<String> list , String replacement  ) {
    StringBuilder b = new StringBuilder();
    for( String item: list ) { 
        b.append( replacement ).append( item );
    }
    return b.toString().substring( replacement.length() );
}

这看起来和最初的问题很相似。

所以如果你不想把整个罐子添加到你的项目中,你可以使用这个。

我认为你原来的代码没有问题。实际上,每个人都建议的替代方案看起来几乎相同(尽管它做了一些额外的验证)

这里有Apache 2.0许可证。

public static String join(Iterator iterator, String separator) {
    // handle null, zero and one elements before building a buffer
    if (iterator == null) {
        return null;
    }
    if (!iterator.hasNext()) {
        return EMPTY;
    }
    Object first = iterator.next();
    if (!iterator.hasNext()) {
        return ObjectUtils.toString(first);
    }

    // two or more elements
    StringBuffer buf = new StringBuffer(256); // Java default is 16, probably too small
    if (first != null) {
        buf.append(first);
    }

    while (iterator.hasNext()) {
        if (separator != null) {
            buf.append(separator);
        }
        Object obj = iterator.next();
        if (obj != null) {
            buf.append(obj);
        }
    }
    return buf.toString();
}

现在我们知道了,谢谢开源