一种逆转java String.split() 效果的方法? [复制]

Posted

技术标签:

【中文标题】一种逆转java String.split() 效果的方法? [复制]【英文标题】:A method to reverse effect of java String.split()? [duplicate] 【发布时间】:2010-10-22 02:37:53 【问题描述】:

我正在寻找一种将字符串数组组合成分隔符的方法 细绳。与 split() 相反。

在我自己写之前想问问论坛(因为JDK什么都有)

【问题讨论】:

只需遍历数组并将元素连接到 StringBuilder 中。 ***.com/questions/63150/…、***.com/questions/448320/…、***.com/questions/205555/…、***.com/questions/58431/… 和其他几个的副本。 谢谢。我确实写过这样的方法,但是在过去多次重新发明***之后,然后发现jdk已经有了它......好吧,认为它是愤怒的帖子.. Phil 你只能估计,如果输入被这样的正则表达式分割:s = "foo:bar,baz".split ("[:,]") 请参阅下面@DenTheMan 的回答 Arrays.toString(Object[]) 【参考方案1】:

据我所知,JDK 中没有用于此的方法。 Apache Commons Lang 在 StringUtils 类中有各种重载的 join() 方法,可以做你想做的事。

【讨论】:

对于未来的读者:Java 8 有一个 String.join() 方法。【参考方案2】:

至少从 2009 年开始就有一个开放的功能请求。总而言之,它将成为 JDK 8 的 java.util.StringJoiner 类功能的一部分。 http://download.java.net/lambda/b81/docs/api/java/util/StringJoiner.html

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

这是一个字符串数组上的新 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);

【讨论】:

【参考方案3】:

您可以从 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("[\\[\\]]", "");

【讨论】:

有点晚了,但这听起来通常是个坏主意,除非您绝对确定字符串中永远不会有 ', '。然后它可能远没有效率。【参考方案4】:

我得到了下面的例子here

/*
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" , "$#$"));
  

【讨论】:

【参考方案5】:

Google 还在他们的 Google Collections 库中提供了一个 joiner 类:

Joiner API

Google Collections

【讨论】:

我总是更喜欢 google apis 而不是 apache.commons。谢谢【参考方案6】:

DZone Snippets 上有几个示例,如果您想推出自己的与集合一起使用的示例。例如:

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();

【讨论】:

我倾向于省略空检查,因为行为将是相同的,为什么在特殊情况下使代码复杂化?另一方面,可能需要进行空检查。 @Carl:我完全同意你的空检查并补充说。检查空集合允许函数跳过不必要的创建迭代器和字符串缓冲区,所以我把它留在里面。 您应该使用 StringBuilder 而不是 StringBuffer,因为 StringBuffer 会增加同步开销。您不需要同步方法变量(因为只有一个线程会使用它)。 您的连接方法应该接受 Collection,而不是 AbstractCollection。更好的是,它可以接受 Iterable,这使得它更通用。 @Steve:其中任何一个都可以接受。您可以根据需要使其抽象或具体。在我链接到的页面上有一个稍后的示例,它接受 Iterable。【参考方案7】:

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

【讨论】:

实际上这也适用于 String[],使用 Arrays.toString(Object[]) 从 Java 1.5 开始可用,该版本于 2004 年发布 eons 在问题出现之前张贴。这是正确的答案,如果您不介意前缀“[”和后缀“]”。【参考方案8】:

根据之前的所有答案:

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();

【讨论】:

我认为这是更好的方法,简单高效。还需要提到的是,apache 使用一个简单的 for 和 if inside,而 openjdk8 做一些类似你的事情,但在分开的方法中。 您会很高兴知道 Java 8 现在允许您使用内置的 String.join() 方法做到这一点。【参考方案9】:

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

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

返回一个字符串,其中包含由分隔符连接的标记。

tokens -- 要加入的数组对象。字符串将通过调用 object.toString() 从对象中形成。

【讨论】:

【参考方案10】:

自从 JDK8 以来,我非常喜欢 Streams 和 Lambdas,所以我建议:

public static String join( String delimiter, String[] array )

    return Arrays.asList( array ).stream().collect( Collectors.joining( delimiter ) );

【讨论】:

【参考方案11】:

为了完整起见,我想补充一点,您一般不能反转 String#split,因为它接受正则表达式。

"hello__world".split("_+"); 收益 ["hello", "world"]."hello_world".split("_+"); 收益 ["hello", "world"].

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

这就是说,如果您假设您的参数是固定字符串,而不是正则表达式,那么您当然可以使用许多发布的答案之一来做到这一点。

【讨论】:

【参考方案12】:

这个也不错:

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;

【讨论】:

@allyourcode 我认为StringBuffer 的使用避免了Schlemiel 问题link +1 指向 Schlemiel 算法!【参考方案13】:

这是我写的:

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();

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

【讨论】:

【参考方案14】:

下面的代码给出了一个基本的想法。虽然这不是最好的解决方案。

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();

【讨论】:

【参考方案15】:

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

我认为这里的许多答案都很复杂或不易阅读。既然分支预测如此高效,为什么你干脆不使用 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 也是这样做的,但在分开的方法调用中而不是一个简单的循环。

【讨论】:

【参考方案16】:

我更喜欢这个:

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;

这是迄今为止我找到的最简洁的解决方案。 (不用担心使用原始 String 对象而不是 StringBuilder。现代 Java 编译器无论如何都使用 StringBuilder,但这段代码更具可读性)。

【讨论】:

这受到 Schlemeil 问题的影响:en.wikipedia.org/wiki/Schlemiel_the_Painter's_algorithm @allyourcode 我以前从未听说过这个问题,谢谢你的链接! @allyourcode 很幸运,如今编译器为像 Schlemeil 这样的笨蛋“移动了油漆罐”。

以上是关于一种逆转java String.split() 效果的方法? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Brief introduction to Java String Split 简单介绍下Java String Split

Java String.split()用法小结

Java String.split()用法小结

java String.split()用法

Java String.split()用法总结整理

Java中split的用法