web-dev-qa-db-ja.com

Java St​​ring.split()の効果を逆にする方法?

文字列の配列を区切り文字列に結合する方法を探しています。 split()の反対。

自分で書いてみる前にフォーラムに質問したかった(JDKにはすべてがあるから)

123
javaphild

私が知っているこの方法はJDKにはありません。 Apache Commons Lang には、 StringUtils クラスのさまざまなオーバーロードjoin()メソッドがあります。

92
John Topley

少なくとも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=501516

更新

文字列の配列での新しい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);
41

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("[\\[\\]]", "");
23
David Howard

私は次の例を取得しました 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" }, "$#$"));
  }
}
16
Azder

Googleは、Googleコレクションライブラリでジョイナークラスも提供しています。

Joiner API

Googleコレクション

12
Blair Zajac

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();
}
10
Bill the Lizard

Int []がある場合、Arrays.toString()が最も簡単な方法です。

7
DenTheMan

以前のすべての回答に基づいて:

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();
}
4
Sarabjot

Androidの場合: Android.text.TextUtils にはメソッドがあります:

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

区切り文字で結合されたトークンを含む文字列を返します。

tokens-結合される配列オブジェクト。 object.toString()を呼び出すことにより、オブジェクトから文字列が形成されます。

JDK8以降、StreamsとLambdasが大好きなので、次のことをお勧めします。

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

これも悪くありません:

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;
}
1
Microscotch

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はこのようなifステートメントを含むシンプルなforループを使用し(最初の要素を知るためにインデックスとして配列を使用します)、openjdk 8は同じことを行いますが、単純なループ。

1
PhoneixS

完全を期すために、正規表現を受け入れるため、一般的に String#split を逆にすることはできないことを付け加えたいと思います。

"hello__world".split("_+");["hello", "world"]を生成します。
"hello_world".split("_+");["hello", "world"]を生成します。

これらは、異なる開始点から同じ結果をもたらします。分割は1対1の操作ではないため、元に戻すことはできません。

これはすべて、パラメーターが正規表現ではなく固定文字列であると仮定した場合、多くの投稿された回答のいずれかを使用してこれを行うことができます。

1
Cruncher

私はこれを書きました:

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

以下のコードは基本的な考え方を示しています。しかしこれは最善の解決策ではありません。

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

私はこれが好きです:

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;
}

これは私がこれまでに見つけた最も近い解決策です。 (StringBuilderの代わりに生のStringオブジェクトを使用することについては心配しないでください。現代のJavaコンパイラはとにかくStringBuilderを使用しますが、このコードは読みやすいです)。

0
Luis