Java:PHPのjoin()のような配列の関数?


259

String[]接着剤の紐でつなぎたい。これに機能はありますか?


7
Java 8には、この機能が標準で含まれています。私は読者に@Marek Gregorの回答までスクロール(そしてそれを賛成投票する)ことをお勧めします
Stav

回答:


307

始まっJava8を使用することが可能ですString.join()

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

生成:

Hello, World, !

それ以外の場合、Apache Commons Langには、配列を結合してを作成する関数をStringUtils持つクラスがあります。joinString

例えば:

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

以下を生成しますString

Hello, World, !

7
この回答を検索する人たちのために、これはPerlの結合に相当することにも注意してください。
k-den

3
それは私には定義されていないと言います
Ninjaxor 2013

@Ninjaxor 1. commons-lang * jarはクラスパスにある必要があります2. import org.apache.commons.lang3.StringUtils;
peterh-モニカを2014年

9
この回答を編集してString.join()、Java 8で導入された新しいメソッドへの参照を追加することをお勧めします。このようにして、この受け入れられた回答を読んでいる膨大な数の人々がその知識から利益を得るでしょう。現在、この事実に言及している最高投票の回答はかなり下に失われています...
Duncan Jones

1
or 要素でString.join()のみ機能することは言及する価値があります。List<CharSequence>CharSequence[]
Enigo 2016年

71

あなたがアンドロイドで何を使うべきかを探していたなら、それは:

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

例えば:

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

2
Java 8はAndroidで少ししか登場しないので、これは明らかにすべてのAndroidバージョンにとって最良の答えです。このソリューションは、これらのばかげた「1つのアクションを実行するための巨大なライブラリを含める」ソリューションではなく、組み込みのAndroidライブラリを使用します。
LukeStoneHm 2015

2017年9月ですが、Java 8 for Androidはまだまだ先です。この回答をありがとう!
Aenadon 2017


53

このような関数は、約10行のコードで簡単に記述できます。

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
あなたによると良い習慣...そのようなことのための普遍的な標準はありません。
フェーバス

24
しかし、中かっこを含めると、2行のコードが追加されてしまい、11行で完了したとは言えませんでした。
ジェイ

8
問題は、しばらくしてから、または誰か他の人が急いでいる場合、中括弧を追加せずにif / forに別の行を追加することです。または、if(k == 0)の後にnullを返します。場合によってはコンパイルされますが、正しくありません。次に、その閉じ中かっこの余分な行を1つ犠牲にすることをお勧めします(行頭は同じif / for行にとどまることができます)。
ミラノ

16
ほとんどの言語がそのような機能をコアに組み込んでいるのに対し、Javaコミュニティは誰もが車輪を再発明することを奨励しているのは素晴らしいことだと思います。
John Strickler、2011

33
11行?ば!1でできる!ソースファイルの改行文字をすべて削除するだけです。
Thomas Eding、2011

25

substring()を使用する代わりに少しmod:

//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

10
7行目:連結してビルダーに追加するのではなく、.append()それぞれ2回使用する方が良いですか?String
Talha Ahmed Khan 2013

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

Googleグアバのライブラリにもこのような機能があります。String []の例は、APIからも確認できます。

すでにAPIで説明されているように、ビルダーメソッドの不変性に注意してください。

それはあなたのケースで動作するようにオブジェクトの配列を受け入れることができます。以前の経験では、反復可能で正常に動作するスタックに参加してみました。

私からのサンプル:

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年

9

Spring Frameworkを使用している場合は、StringUtilsクラスがあります。

import static org.springframework.util.StringUtils.arrayToDelimitedString;

arrayToDelimitedString(new String[] {"A", "B", "C"}, "\n");

8

コアではありません。「java array join string glue」を検索すると、これを実現する方法のコードスニペットがいくつか表示されます。

例えば

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
パフォーマンスを向上させるには、StringBuffer(スレッドセーフ)の代わりにStringBuilder(非スレッドセーフ)を使用します。インターフェースは同じです。
Asaph

2
これはsnippets.dzone.com/posts/show/91にあるようです。コメントは大幅に改善されたバージョンを示唆しています:public static String join(Iterable <?extends Object> pColl、String separator){Iterator <?Object> oIter;を拡張します。if(pColl == null ||(!(oIter = pColl.iterator()).hasNext()))return ""; StringBuilder oBuilder = new StringBuilder(String.valueOf(oIter.next())); while(oIter.hasNext())oBuilder.append(separator).append(oIter.next()); oBuilder.toString();を返す }
Quantum7、2010年

6

配列から文字列への迅速な変換を求めてここに着いた場合は、Arrays.toString()を試してください。

Object[]渡された文字列表現を作成します。結果は角括弧("[]")で囲まれ、各要素はを介して文字列に変換され、String.valueOf(Object)で区切られ", "ます。配列の場合 nullは、"null"返されます。


どうもありがとう!文字列は「、」で区切られており、全体が「[]」で囲まれています。
John Henckel 2014

5

ちょうどのために、「私は最短1をした」挑戦、ここでは鉱山です。)

反復:

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
再帰バージョンはエレガントです。間違いなくそれを使用します。
ピート14年

再帰バージョンは洗練されているかもしれませんが、大きな配列( " copyOfRange()")には非効率的です。
Ogre Psalm33 2017年


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クラスのメソッドのみを使用する私の3行の方法が好きですか?

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
岡良一郎

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(プラス演算子を使用した文字列連結)は、を使用する目的全体を無効にしますStringBuilder
quietmint 2013年

さらに、このアプローチは、区切り文字 ":"を含む{"foo"、 "bar"}のような配列が "foo:bar:"に
変わることを意味し

-2

私がよく使う簡単な速記テクニックがあります。

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

これは、長さ1の区切り文字でのみ機能し、別の長さの区切り文字が必要な場合は、「非常にローカルではありますが」「マジックナンバー」が必要です。
maiwald 2013年

追加時に複数の文字を追加できます
Gaurav Adurkar '10年

単に行うより: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
問題は、文字列の配列を区切り文字で結合する方法であり、2つの文字列の配列を結合する方法ではありません。
toolbear 2010年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.