Java数组的函数是否类似于PHP中的join()函数?

270

我想用一个粘合字符串(glue string)连接一个String[]数组,有没有相关的函数可以实现这个目的?


7
Java 8已经默认包含了这个功能。我建议读者滚动查看@Marek Gregor的答案(并点赞...)。 - stav
可能是[A quick and easy way to join array elements with a separator (the opposite of split) in Java]的重复问题。(https://dev59.com/q3I-5IYBdhLWcg3wMFMf) - Anderson Green
24个回答

6
如果您在寻找快速的数组转字符串转换,可以尝试使用 Arrays.toString()
该方法会创建一个 Object[] 的字符串表示形式。结果用方括号(“[]”)括起来,并通过 String.valueOf(Object) 转换每个元素为字符串,以“,”分隔。如果数组为 null,则返回“null”。

非常感谢!这些字符串由", "分隔,并且整个内容都包含在"[]"中,这对我来说没问题。 - John Henckel

5

为了应对“我拥有最短的代码”的挑战,这里是我的代码;)

迭代法:

public static String join(String s, Object... a) {
    StringBuilder o = new StringBuilder();
    for (Iterator<Object> i = Arrays.asList(a).iterator(); i.hasNext();)
        o.append(i.next()).append(i.hasNext() ? s : "");
    return o.toString();
}

递归:

public static String join(String s, Object... a) {
    return a.length == 0 ? "" : a[0] + (a.length == 1 ? "" : s + join(s, Arrays.copyOfRange(a, 1, a.length)));
}

2
递归版本很优雅。肯定会使用它。 - Pete
递归版本可能更优雅,但对于大数组而言效率低下(“copyOfRange()”)。 - Ogre Psalm33

4

据我所知,没有内置的方法可以实现此功能。

Apache Commons Lang 提供了一个叫做 StringUtils 的类,其中包含许多连接函数。


4

这是我的做法。

private String join(String[] input, String delimiter)
{
    StringBuilder sb = new StringBuilder();
    for(String value : input)
    {
        sb.append(value);
        sb.append(delimiter);
    }
    int length = sb.length();
    if(length > 0)
    {
        // Remove the extra delimiter
        sb.setLength(length - delimiter.length());
    }
    return sb.toString();
}

2
一个类似的替代方案。
/**
 * @param delimiter 
 * @param inStr
 * @return String
 */
public static String join(String delimiter, String... inStr)
{
    StringBuilder sb = new StringBuilder();
    if (inStr.length > 0)
    {
        sb.append(inStr[0]);
        for (int i = 1; i < inStr.length; i++)
        {
            sb.append(delimiter);                   
            sb.append(inStr[i]);
        }
    }
    return sb.toString();
}

2

我的见解。

public static String join(Object[] objects, String delimiter) {
  if (objects.length == 0) {
    return "";
  }
  int capacityGuess = (objects.length * objects[0].toString().length())
      + ((objects.length - 1) * delimiter.length());
  StringBuilder ret = new StringBuilder(capacityGuess);
  ret.append(objects[0]);
  for (int i = 1; i < objects.length; i++) {
    ret.append(delimiter);
    ret.append(objects[i]);
  }
  return ret.toString();
}

public static String join(Object... objects) {
  return join(objects, "");
}

1
你喜欢我使用 String 类的方法只用三行实现的方式吗?
static String join(String glue, String[] array) {
    String line = "";
    for (String s : array) line += s + glue;
    return (array.length == 0) ? line : line.substring(0, line.length() - glue.length());
}

1
这并不是为了效率而设计的。如果你需要效率,请使用 StringBuilder :P - Ryoichiro Oka

0

如果你正在使用Functional Java库,但由于某些原因无法使用Java 8的Streams(当使用Android + Retrolambda插件时可能会出现这种情况),那么这里有一个功能性的解决方案:

String joinWithSeparator(List<String> items, String separator) {
    return items
            .bind(id -> list(separator, id))
            .drop(1)
            .foldLeft(
                    (result, item) -> result + item,
                    ""
            );
}

请注意,这不是最有效的方法,但对于小列表来说效果很好。

0

如前所述,自Java 8以来,StringJoiner类也是一种可用的选项:

@NotNull
String stringArrayToCsv(@NotNull String[] data) {
    if (data.length == 0) {return "";}
    StringJoiner joiner = new StringJoiner(", ");
    Iterator<String> itr = Arrays.stream(data).iterator();
    while (itr.hasNext()) {joiner.add(itr.next());}
    return joiner.toString();
}

然而,传统的String.join()更简洁、代码量更少:

@NotNull
String stringArrayToCsv(@NotNull String[] data) {
    if (data.length == 0) {return "";}
    return String.join(", ", data);
}

0
无论您选择哪种方法,请注意数组中的空值。它们的字符串表示形式为“null”,因此如果这不是您期望的行为,请跳过空元素。
String[] parts = {"Hello", "World", null, "!"};
Stream.of(parts)
      .filter(Objects::nonNull)
      .collect(Collectors.joining(" "));

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接