Java:像PHP的join()这样的数组函数?


Answers:


307

Java8开始,可以使用String.join()

String.join(", ", new String[]{"Hello", "World", "!"})

产生:

Hello, World, !

否则,Apache Commons Lang有一个StringUtils类,该类具有join将数组连接在一起以构成的功能String

例如:

StringUtils.join(new String[] {"Hello", "World", "!"}, ", ")

生成以下内容String

Hello, World, !

7
为了使人们能够找到这个答案,应该注意,这也等同于Perl连接。
k-den

3
它说对我来说是不确定的
Ninjaxor

@Ninjaxor 1. commons-lang * jar必须在类路径中。2. import org.apache.commons.lang3.StringUtils;
彼得-恢复莫妮卡2014年

9
我建议您编辑此答案,以附加对String.join()Java 8中引入的新方法的引用。这样,大量阅读此公认答案的人将从中受益。目前,提到这一事实的投票率最高的答案是在下面落败了……
Duncan Jones

1
值得一提的是,String.join()仅适用于List<CharSequence>CharSequence[]元素。
Enigo

71

如果您正在寻找要在android中使用的内容,则为:

String android.text.TextUtils.join(CharSequence delimiter, Object[] tokens)

例如:

String joined = TextUtils.join(";", MyStringArray);

2
显然,这是所有Android版本的最佳答案,因为Java 8仅在Android上出现了一点。该解决方案使用内置的Android库,而不是这些愚蠢的“包括执行一个动作的巨大库”解决方案。
LukeStoneHm 2015年

到了2017年9月,离Android的Java 8还很遥远。感谢您的回答!
Aenadon


53

您可以轻松地用大约十行代码编写这样的函数:

String combine(String[] s, String glue)
{
  int k = s.length;
  if ( k == 0 )
  {
    return null;
  }
  StringBuilder out = new StringBuilder();
  out.append( s[0] );
  for ( int x=1; x < k; ++x )
  {
    out.append(glue).append(s[x]);
  }
  return out.toString();
}

35
根据您的良好做法...对于此类事物没有统一的标准。
phoebus

24
但是,如果我包含花括号,那将再增加两行代码,而我不能声称已经在11行中做到了!
杰伊,

8
问题是,如果您过了一会儿或其他人急于在不添加括号的情况下在该行添加另一行;或在if(k == 0)之后删除return null,在某些情况下会编译但不正确。然后最好为该闭合括号牺牲一条额外的行(如果/行可以保持同一行的开口)。
米兰2010年

16
我认为,虽然大多数语言都将此类功能打包到其核心中,但真是太棒了,Java社区鼓励所有人重新发明轮子。
John Strickler

33
11行?呸! 我可以在1中完成!只需删除源文件中的所有换行符。
Thomas Eding

25

一个小的mod,而不是使用substring():

//join(String array,delimiter)
public static String join(String r[],String d)
{
        if (r.length == 0) return "";
        StringBuilder sb = new StringBuilder();
        int i;
        for(i=0;i<r.length-1;i++){
            sb.append(r[i]);
            sb.append(d);
        }
        sb.append(r[i]);
        return sb.toString();
}

投票是因为您不需要添加任何库。
givanse 2012年

10
第7行:如果.append()每个都使用两次String而不是将它们串联然后附加到构建器,会更好吗?
Talha Ahmed Khan

18

与最近的许多问题一样,Java 8可以帮助您:


Java 8添加了一个新的静态方法,java.lang.String该方法完全可以实现您想要的功能:

public static String join(CharSequence delimeter, CharSequence... elements);

使用它:

String s = String.join(", ", new String[] {"Hello", "World", "!"});

结果是:

"Hello, World, !"

14

谷歌番石榴的图书馆也具有这种能力。您也可以从API中看到String []示例。

正如api中已经描述的那样,请注意构建器方法的不变性。

它可以接受一系列对象,因此可以根据您的情况使用。根据我以前的经验,我尝试加入一个可迭代的Stack,并且效果很好。

来自我的样本:

Deque<String> nameStack = new ArrayDeque<>();
nameStack.push("a coder");
nameStack.push("i am");
System.out.println("|" + Joiner.on(' ').skipNulls().join(nameStack) + "|");

打印出: |i am a coder|


9

鉴于:

String[] a = new String[] { "Hello", "World", "!" };

然后,作为替代coobird的答案,胶水为“,”:

Arrays.asList(a).toString().replaceAll("^\\[|\\]$", "")

或与其他字符串连接,例如“&amp;”。

Arrays.asList(a).toString().replaceAll(", ", " &amp; ").replaceAll("^\\[|\\]$", "")

但是...仅当您知道数组或列表中的值不包含字符串“,”时,此方法才有效。


Arrays.asList(a).toString()为我想做的事工作
所罗门·乌科,2016年


8

不是核心,不。搜索“ java数组连接字符串胶水”将为您提供一些有关如何实现此功能的代码段。

例如

public static String join(Collection s, String delimiter) {
    StringBuffer buffer = new StringBuffer();
    Iterator iter = s.iterator();
    while (iter.hasNext()) {
        buffer.append(iter.next());
        if (iter.hasNext()) {
            buffer.append(delimiter);
        }
    }
    return buffer.toString();
}

2
使用StringBuilder(非线程安全)代替StringBuffer(线程安全)可获得更好的性能。接口是一样的。
Asaph,2009年

2
这似乎来自snippets.dzone.com/posts/show/91。这些注释提出了一个经过改进的版本:public static String join(Iterable <?扩展Object> pColl,String分隔符){Iterator <?扩展Object> oIter; 如果(pColl == null ||(!(oIter = pColl.iterator()).hasNext()))返回“”;StringBuilder oBuilder = new StringBuilder(String.valueOf(oIter.next())); while(oIter.hasNext())oBuilder.append(eparator).append(oIter.next()); 返回oBuilder.toString(); }
Quantum10年

6

如果您在这里寻找快速的数组到字符串转换,请尝试Arrays.toString()

创建Object[]传递的字符串表示形式。结果用方括号("[]")括起来,每个元素通过String.valueOf(Object)和转换为字符串,并用分隔", "。如果数组是 null,则"null"返回。


非常感谢!字符串之间用“,”分隔,整个内容周围带有“ []”,这对我来说很好。
约翰·亨克

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
递归版本很优雅。绝对会使用它。
皮特

递归版本可能很优雅,但是对于大型数组(“ copyOfRange()”)而言效率很低。
食人魔赞美诗


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 2014年

0

要从“ str1”,“ str2”,“”获得“ str1,str2”:

Stream.of("str1", "str2", "").filter(str -> !str.isEmpty()).collect(Collectors.joining(", ")); 

您也可以添加额外的空检查


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,
                    ""
            );
}

请注意,这不是最有效的方法,但对于小型列表确实有效。


-1

我使用StringBuilder这样做:

public static String join(String[] source, String delimiter) {
    if ((null == source) || (source.length < 1)) {
        return "";
    }

    StringBuilder stringbuilder = new StringBuilder();
    for (String s : source) {
        stringbuilder.append(s + delimiter);
    }
    return stringbuilder.toString();
} // join((String[], String)

1
s + delimiter(使用plus运算符进行字符串连接)无法实现使用的全部目的StringBuilder
2013年

另外,这种方法意味着将带有分隔符“:”的{:foo“,” bar“}这样的数组转换为” foo:bar:“
pioto 2014年

-2

我经常使用简单的速记技术。

String op = new String;
for (int i : is) 
{
    op += candidatesArr[i-1]+",";
}
op = op.substring(0, op.length()-1);

这仅适用于长度为1的定界符,并且如果需要不同长度的定界符,则需要“魔数”(尽管相当局部)。
麦瓦尔德

您可以在追加时添加多个字符
Gaurav Adurkar,

比简单地做:op = op.substring(0,op.length()-“,”。length()); 有什么大不了的?
丹尼斯

-3

java.util.Arrays具有一个'asList'方法。与java.util.List / ArrayList API一起,可以为您提供所需的一切:

private static String[] join(String[] array1, String[] array2) {

    List<String> list = new ArrayList<String>(Arrays.asList(array1));
    list.addAll(Arrays.asList(array2));
    return list.toArray(new String[0]);
}

7
问题是如何用定界符连接字符串数组,而不是如何将两个字符串数组连接在一起。
toolbear 2010年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.