使用Java中的分隔符(与split相反)连接数组元素的快速简便方法

Era*_*dan 432 java arrays string

请参阅相关的.NET问题

我正在寻找一种快速简便的方法来完成与分裂完全相反的方式,以便它 ["a","b","c"]能够成为"a,b,c"

迭代数组需要添加条件(如果这不是最后一个元素,添加分隔符)或使用子字符串删除最后一个分隔符.

我确信有一种经过认证的有效方法(Apache Commons?)

您更喜欢在项目中做到这一点?

ski*_*iwi 694

使用Java 8,您可以以非常干净的方式执行此操作:

String.join(delimiter, elements);
Run Code Online (Sandbox Code Playgroud)

这有三种方式:

1)直接指定元素

String joined1 = String.join(",", "a", "b", "c");
Run Code Online (Sandbox Code Playgroud)

2)使用数组

String[] array = new String[] { "a", "b", "c" };
String joined2 = String.join(",", array);
Run Code Online (Sandbox Code Playgroud)

3)使用iterables

List<String> list = Arrays.asList(array);
String joined3 = String.join(",", list);
Run Code Online (Sandbox Code Playgroud)

  • 他们花了8个主要版本来实现这个基本和有用的东西?希望我可以为此向下投票. (86认同)
  • 我以前的评论中的OK重点使用不正确.我的观点是我们只能将它用于像Char这样的`CharSequence`元素(例如有问题的例子),但最好添加一个信息,这个方法不适用于我们需要的`Person`,`Car`这样的元素.显式调用`toString`. (7认同)
  • 我们应该提到这种方法仅用于`List <CharSequence>`或`CharSequence []`元素,如`字符串`,`StringBuilder`的列表或数组. (5认同)
  • 不幸的是,"Android Studio"并不完全支持1.8仅1.7:http://stackoverflow.com/q/31528782/239219 (3认同)
  • 对于数组或对象列表,您可以使用流(Java 8):`Arrays.steam(array).map(String::valueOf).collect(Collectors.joining(delimiter));` (2认同)

nmr*_*nmr 287

如果你在Android上,你可以 TextUtils.join(delimiter, tokens)

  • 仍然是最佳答案,因为接受需要 API 级别 26。 (7认同)

nd.*_*nd. 114

对于这个特殊问题,我更喜欢Google Collections而不是Apache StringUtils:

Joiner.on(separator).join(array)
Run Code Online (Sandbox Code Playgroud)

与StringUtils相比,Joiner API具有流畅的设计并且更加灵活,例如null元素可以被跳过或替换为占位符.此外,Joiner还具有使用键和值之间的分隔符连接地图的功能.

  • 但是,这只接受`Iterable <?>`,因此必须重新输入简单的数组. (4认同)
  • 必须调用**skipNulls**`Joiner.on(separator).skipNulls().join(array)` (3认同)
  • @anoniim Joiner.join在现在的Google Guava中为Iterable和Arrays重载:http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/com/google/common/base/ Joiner.html#加入(java.lang.Object中[]) (2认同)
  • 啊,你说得对.我不小心使用了`com.google.api.client.util.Joiner`而不是`com.google.common.base.Joiner`,它同时接受Iterable和Array. (2认同)

coo*_*ird 105

Apache Commons Lang确实有一种StringUtils.join方法可以将String数组与指定的分隔符连接在一起.

例如:

String[] s = new String[] {"a", "b", "c"};
String joined = StringUtils.join(s, ",");  // "a,b,c"
Run Code Online (Sandbox Code Playgroud)

但是,我怀疑,正如你所提到的,在上述方法的实际实现中必须有某种条件或子串处理.

如果我要执行String加入并且没有任何其他理由使用Commons Lang,我可能会自己动手来减少对外部库的依赖数量.


小智 45

没有任何第三方的快速简单的解决方案包括.

public static String strJoin(String[] aArr, String sSep) {
    StringBuilder sbStr = new StringBuilder();
    for (int i = 0, il = aArr.length; i < il; i++) {
        if (i > 0)
            sbStr.append(sSep);
        sbStr.append(aArr[i]);
    }
    return sbStr.toString();
}
Run Code Online (Sandbox Code Playgroud)

  • @BPS实际上,如果你考虑快速,你可以依靠由于CPU前瞻而优化的`i> 0`.请考虑http://stackoverflow.com/q/11227809/330057 (8认同)
  • 'i> 0'检查也用于apache commons实现.仅在第一次迭代中检查为false. (3认同)

Rol*_*man 24

"我确信有一种经过认证的有效方法(Apache Commons?)"

是的,明显的是它

StringUtils.join(array, separator)
Run Code Online (Sandbox Code Playgroud)

http://www.java2s.com/Code/JavaAPI/org.apache.commons.lang/StringUtilsjoinObjectarrayStringseparator.htm

  • 哦,对不起,我不是要冒犯你。如果您的解决方案具有广泛的适用范围,或者在更大的数据基础上它的表现有所不同,那我就错过了一些提示。我认为最好是改善现有答案以提供有用的信息,而不是添加第16个答案:) (2认同)

eiv*_*ndw 19

使用Java 1.8,有一个新的StringJoiner类 - 所以不需要Guava或Apache Commons:

String str = new StringJoiner(",").add("a").add("b").add("c").toString();
Run Code Online (Sandbox Code Playgroud)

或直接使用新流api的集合:

String str = Arrays.asList("a", "b", "c").stream().collect(Collectors.joining(","));
Run Code Online (Sandbox Code Playgroud)


ale*_*exm 18

你甚至可以更容易地使用Arrays,因此你将获得一个String,其中数组的值由","分隔

String concat = Arrays.toString(myArray);
Run Code Online (Sandbox Code Playgroud)

所以你最终得到这个:concat ="[a,b,c]"

更新

然后,您可以使用Jeff建议的子字符串去掉括号

concat = concat.substring(1, concat.length() -1);
Run Code Online (Sandbox Code Playgroud)

所以你最终得到了concat ="a,b,c"

  • 不不不!`Arrays.toString`的javadoc没有声明它将返回`[a,b,c]`.它声明了这个*返回指定数组*的内容的字符串表示,它只是一个文本表示.不要依赖于实现细节,因为`Arrays.toString`实现理论上可能有一天会改变.如果有其他方法,切勿从字符串表示中提取数据. (12认同)
  • 这是一种可怕的黑客行为,它依赖于一个数组的字符串表示形式。 (2认同)

wad*_*man 16

您可以将replace和replaceAll与正则表达式一起使用.

String[] strings = {"a", "b", "c"};

String result = Arrays.asList(strings).toString().replaceAll("(^\\[|\\]$)", "").replace(", ", ",");
Run Code Online (Sandbox Code Playgroud)

因为Arrays.asList().toString()产生:"[a,b,c]",我们做一个replaceAll删除第一个和最后一个括号然后(可选)你可以改变","(你的新分隔符)的","序列.

剥离版本(更少的字符):

String[] strings = {"a", "b", "c"};

String result = ("" + Arrays.asList(strings)).replaceAll("(^.|.$)", "").replace(", ", "," );
Run Code Online (Sandbox Code Playgroud)

正则表达式非常强大,特别是String方法"replaceFirst"和"replaceAll".试一试.

  • 这是一种安全的方法吗?List.toString()的输出是否保证不会在新Java版本中更改? (8认同)

Aja*_*jax 8

所有这些其他答案都包括运行时开销......比如使用ArrayList.toString().replaceAll(...)非常浪费.

我会给你一个零开销的最优算法; 它看起来不像其他选项那么漂亮,但在内部,这是他们都在做的事情(在成堆的其他隐藏检查,多个数组分配和其他crud之后).

由于您已经知道正在处理字符串,因此可以通过手动执行所有操作来节省大量数组分配.这不是很好,但是如果你跟踪其他实现所做的实际方法调用,你会发现它的运行时开销最小.

public static String join(String separator, String ... values) {
  if (values.length==0)return "";//need at least one element
  //all string operations use a new array, so minimize all calls possible
  char[] sep = separator.toCharArray();

  // determine final size and normalize nulls
  int totalSize = (values.length - 1) * sep.length;// separator size
  for (int i = 0; i < values.length; i++) {
    if (values[i] == null)
      values[i] = "";
    else
      totalSize += values[i].length();
  }

  //exact size; no bounds checks or resizes
  char[] joined = new char[totalSize];
  int pos = 0;
  //note, we are iterating all the elements except the last one
  for (int i = 0, end = values.length-1; i < end; i++) {
    System.arraycopy(values[i].toCharArray(), 0, 
      joined, pos, values[i].length());
    pos += values[i].length();
    System.arraycopy(sep, 0, joined, pos, sep.length);
    pos += sep.length;
  }
  //now, add the last element; 
  //this is why we checked values.length == 0 off the hop
  System.arraycopy(values[values.length-1].toCharArray(), 0,
    joined, pos, values[values.length-1].length());

  return new String(joined);
}
Run Code Online (Sandbox Code Playgroud)

  • 有趣.你有一些基准测试表明你的实现比Google集合/ Apache公共更快吗?如果是这样,两者都是开源的,我鼓励你提交拉取请求. (4认同)

mne*_*rco 6

这个选项快速而清晰:

  public static String join(String separator, String... values) {
    StringBuilder sb = new StringBuilder(128);
    int end = 0;
    for (String s : values) {
      if (s != null) {
        sb.append(s);
        end = sb.length();
        sb.append(separator);
      }
    }
    return sb.substring(0, end);
  }
Run Code Online (Sandbox Code Playgroud)


SSp*_*oke 5

这个小功能总是派上用场。

public static String join(String[] strings, int startIndex, String separator) {
    StringBuffer sb = new StringBuffer();
    for (int i=startIndex; i < strings.length; i++) {
        if (i != startIndex) sb.append(separator);
        sb.append(strings[i]);
    }
    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

467922 次

最近记录:

8 年,4 月 前