一个方法来扭转效果的Java String.split()?

我正在寻找一种方法来将一个string数组合并为一个分隔string。 与split()相反。 我以其他语言见过

在我尝试编写自己的程序之前,想问问论坛(因为JDK拥有一切…)

谢谢,

JDK没有这方面的方法,我知道。 Apache Commons Lang在StringUtils类中有各种重载的join()方法,可以做你想做的事情。

至less从2009年开始就有了一个开放的function请求。它的缺点是,它将成为JDK 8的java.util.StringJoiner类的一部分function。 http://download.java.net/lambda/b81/docs/api/java/util/StringJoiner.html

如果你有兴趣,这里是Oracle的问题。 http://bugs.sun.com/view_bug.do?bug_id=5015163

更新

以下是String数组上新增的JDK 8 StringJoiner示例

 String[] a = new String[]{"first","second","third"}; StringJoiner sj = new StringJoiner(","); for(String s:a) sj.add(s); System.out.println(sj); //first,second,third 

String中的一个实用方法使得它更简单:

 String s = String.join(",", stringArray); 

您可以将此function从Arrays实用程序包中移出。

 import java.util.Arrays; ... String delim = ":", csv_record = "Field0:Field1:Field2", fields[] = csv_record.split(delim); String rebuilt_record = Arrays.toString(fields).replace(", ", delim).replaceAll("[\\[\\]]", ""); 

我在这里得到了下面的例子

 /* 7) Join Strings using separator >>>AB$#$CD$#$EF */ import org.apache.commons.lang.StringUtils; public class StringUtilsTrial { public static void main(String[] args) { // Join all Strings in the Array into a Single String, separated by $#$ System.out.println("7) Join Strings using separator >>>" + StringUtils.join(new String[] { "AB", "CD", "EF" }, "$#$")); } } 

Google还在其Google Collections库中提供了一个joiner类:

Joiner API

Googlecollections集

在DZone片段中有几个例子,如果你想推出自己的作品集合。 例如:

 public static String join(AbstractCollection<String> s, String delimiter) { if (s == null || s.isEmpty()) return ""; Iterator<String> iter = s.iterator(); StringBuilder builder = new StringBuilder(iter.next()); while( iter.hasNext() ) { builder.append(delimiter).append(iter.next()); } return builder.toString(); } 

如果你有一个int [], Arrays.toString()是最简单的方法。

根据所有以前的答案:

 public static String join(Iterable<? extends Object> elements, CharSequence separator) { StringBuilder builder = new StringBuilder(); if (elements != null) { Iterator<? extends Object> iter = elements.iterator(); if(iter.hasNext()) { builder.append( String.valueOf( iter.next() ) ); while(iter.hasNext()) { builder .append( separator ) .append( String.valueOf( iter.next() ) ); } } } return builder.toString(); } 

对于Android:在android.text.TextUtils中有方法:

 public static String join (CharSequence delimiter, Iterable tokens) public static String join (CharSequence delimiter, Object[] tokens) 

返回包含由分隔符连接的令牌的string。

标记 – 要join的数组对象。 string将通过调用object.toString()从对象中形成。

这个也不错:

 public static String join(String delimitor,String ... subkeys) { String result = null; if(null!=subkeys && subkeys.length>0) { StringBuffer joinBuffer = new StringBuffer(subkeys[0]); for(int idx=1;idx<subkeys.length;idx++) { joinBuffer.append(delimitor).append(subkeys[idx]); } result = joinBuffer.toString(); } return result; } 

我写了这个:

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

Collection不被JSP支持,所以对于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, ", ")} 

为了完整起见,我想补充一点,不能反向String#split ,因为它接受一个正则expression式。

"hello__world".split("_+"); 产量["hello", "world"]
"hello_world".split("_+"); 产量["hello", "world"]

这些从不同的起点产生相同的结果。 拆分不是一对一的操作,因此是不可逆的。

这一切说,如果你假设你的参数是一个固定的string,而不是正则expression式,那么你当然可以使用其中一个发布的答案。

下面的代码给出一个基本的想法 这不是最好的解决scheme。

 public static String splitJoin(String sourceStr, String delim,boolean trim,boolean ignoreEmpty){ return join(Arrays.asList(sourceStr.split(delim)), delim, ignoreEmpty); } public static String join(List<?> list, String delim, boolean ignoreEmpty) { int len = list.size(); if (len == 0) return ""; StringBuilder sb = new StringBuilder(list.get(0).toString()); for (int i = 1; i < len; i++) { if (ignoreEmpty && !StringUtils.isBlank(list.get(i).toString())) { sb.append(delim); sb.append(list.get(i).toString().trim()); } } return sb.toString(); } 

由于JDK8我喜欢Streams和Lambdas很多,所以我会build议:

 public static String join( String delimiter, String[] array ) { return Arrays.asList( array ).stream().collect( Collectors.joining( delimiter ) ); } 

我更喜欢这个:

 public String join(Collection<String> strCollection, String delimiter) { String joined = ""; int noOfItems = 0; for (String item : strCollection) { joined += item; if (++noOfItems < strCollection.size()) joined += delimiter; } return joined; } 

这是迄今为止我find的最好的解决scheme。 (不要担心使用原始String对象而不是StringBuilder,现代Java编译器无论如何都使用StringBuilder,但是这个代码更具可读性)。

如果您使用jdk8,请参阅@Nathaniel Johnson的答案,因为这样更好。

我认为这里的答案很多很复杂或者不容易阅读。 分支预测如此高效,为什么你根本不使用if语句?

 public static String join(List<String> fooList){ if (fooList.isEmpty()) return ""; StringBuilder sb = null; for (String element : fooList) { if (sb == null) { sb = new StringBuilder(); } else { sb.append(", "); } sb.append(element); } return sb.toString(); } 

应该提到的一点是,Apache使用一个简单的for循环,其中包含一个if语句(它使用一个数组作为它的索引来知道第一个元素),而openjdk 8也是这样做的,但是在分离的方法调用中,简单的循环。