Java: berfungsi untuk array seperti gabungan PHP ()?


Jawaban:


307

Mulai dari Java8 dimungkinkan untuk digunakan String.join().

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

Menghasilkan:

Hello, World, !

Jika tidak, Apache Commons Lang memiliki StringUtilskelas yang memiliki joinfungsi yang akan bergabung dengan array untuk membuat String.

Sebagai contoh:

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

Menghasilkan yang berikut String:

Hello, World, !

7
Demi kepentingan orang yang mencari jawaban ini, mungkin perlu dicatat bahwa ini juga setara dengan gabungan Perl.
k-den

3
ia mengatakan itu tidak didefinisikan untukku
Ninjaxor

@Ninjaxor 1. jar commons-lang * harus berada di classpath 2. import org.apache.commons.lang3.StringUtils;
peterh

9
Saya akan merekomendasikan Anda mengedit jawaban ini untuk menambahkan referensi ke String.join()metode baru yang diperkenalkan di Jawa 8. Dengan cara ini, sejumlah besar orang yang membaca jawaban yang diterima ini akan mendapat manfaat dari pengetahuan itu. Saat ini, jawaban tertinggi yang menyebutkan fakta ini agak hilang di bawah ...
Duncan Jones

1
Perlu disebutkan bahwa String.join()hanya akan berfungsi untuk List<CharSequence>atau CharSequence[]elemen.
Enigo

71

Jika Anda mencari apa yang harus digunakan di Android, itu adalah:

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

sebagai contoh:

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

2
Ini jelas jawaban terbaik untuk semua versi Android, karena Java 8 hanya keluar di Android sedikit. Solusi ini menggunakan lib Android bawaan, daripada solusi konyol ini "sertakan lib besar untuk melakukan satu tindakan".
LukeStoneHm

Ini September 2017, Java 8 untuk Android masih jauh. Terima kasih atas jawaban ini!
Aenadon


53

Anda dapat dengan mudah menulis fungsi seperti itu di sekitar sepuluh baris kode:

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
Praktek yang baik menurut Anda ... tidak ada standar universal untuk hal-hal seperti itu.
phoebus

24
Tetapi jika saya memasukkan kawat gigi, itu akan menambahkan dua baris kode lagi, dan saya tidak bisa mengklaim telah melakukannya dalam 11 baris!
Jay

8
masalahnya adalah ketika Anda setelah beberapa saat, atau orang lain, dengan tergesa-gesa, tambahkan baris lain untuk itu jika / untuk tanpa menambahkan kawat gigi; atau hapus kembali nol setelah jika (k == 0), yang dalam beberapa kasus akan mengkompilasi tetapi akan salah. Maka lebih baik untuk mengorbankan satu baris tambahan untuk kurung tutup itu (pembukaan bisa tetap di baris if / for yang sama).
milan

16
Saya pikir itu luar biasa bahwa sementara sebagian besar bahasa mengemas fungsionalitas seperti itu ke dalam inti mereka, komunitas Java mendorong semua orang untuk menemukan kembali roda.
John Strickler

33
11 baris? Bah! Saya bisa melakukannya dalam 1! Cukup hapus semua karakter baris baru di file sumber.
Thomas Eding

25

Mod kecil alih-alih menggunakan substring ():

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

Dipilih karena Anda tidak perlu menambahkan perpustakaan apa pun.
givanse

10
Baris 7: Apakah lebih baik jika digunakan .append()dua kali untuk masing-masing Stringalih-alih menggabungkannya dan kemudian menambahkan ke pembangun.
Talha Ahmed Khan

18

Seperti banyak pertanyaan belakangan ini, Java 8 menyelamatkan:


Java 8 menambahkan metode statis baru java.lang.Stringyang melakukan persis apa yang Anda inginkan:

public static String join(CharSequence delimeter, CharSequence... elements);

Menggunakannya:

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

Hasil dalam:

"Hello, World, !"

14

Perpustakaan Google jambu biji juga memiliki kemampuan semacam ini . Anda dapat melihat contoh String [] dari API.

Seperti yang sudah dijelaskan dalam api, berhati-hatilah terhadap ketidakmampuan metode pembangun.

Itu dapat menerima berbagai objek sehingga itu akan berfungsi dalam kasus Anda. Dalam pengalaman saya sebelumnya, saya mencoba bergabung dengan Stack yang merupakan iterable dan berfungsi dengan baik.

Contoh dari saya:

Deque<String> nameStack = new ArrayDeque<>();
nameStack.push("a coder");
nameStack.push("i am");
System.out.println("|" + Joiner.on(' ').skipNulls().join(nameStack) + "|");

mencetak: |i am a coder|


9

Diberikan:

String[] a = new String[] { "Hello", "World", "!" };

Kemudian sebagai alternatif untuk jawaban coobird, di mana lemnya adalah ",":

Arrays.asList(a).toString().replaceAll("^\\[|\\]$", "")

Atau untuk digabungkan dengan string yang berbeda, seperti "& amp;".

Arrays.asList(a).toString().replaceAll(", ", " &amp; ").replaceAll("^\\[|\\]$", "")

Namun ... ini HANYA berfungsi jika Anda tahu bahwa nilai-nilai dalam array atau daftar JANGAN berisi string karakter ",".


Arrays.asList(a).toString()bekerja untuk apa yang ingin saya lakukan
Solomon Ucko


8

Tidak pada intinya, tidak. Pencarian untuk "java array join string lem" akan memberi Anda beberapa cuplikan kode tentang cara mencapai ini.

misalnya

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
Gunakan StringBuilder (non-thread-safe) sebagai pengganti StringBuffer (thread-safe) untuk kinerja yang lebih baik. Antarmukanya sama.
Asaf

2
Ini sepertinya dari snippets.dzone.com/posts/show/91 . Komentar menyarankan versi yang jauh lebih baik: public static String join (Iterable <? Extends Object> pColl, String separator) {Iterator <? extends Object> oIter; if (pColl == null || (! (oIter = pColl.iterator ()) .hasNext ())) mengembalikan ""; StringBuilder oBuilder = StringBuilder baru (String.valueOf (oIter.next ())); while (oIter.hasNext ()) oBuilder.append (separator) .append (oIter.next ()); return oBuilder.toString (); }
Quantum7

6

Jika Anda mendarat di sini mencari konversi array-ke-string cepat, coba Array.toString () .

Membuat representasi String dari yang Object[]berlalu. Hasilnya dikelilingi oleh tanda kurung ( "[]"), setiap elemen dikonversi ke String melalui String.valueOf(Object)dan dipisahkan oleh ", ". Jika arraynya null, maka "null"dikembalikan.


TERIMA KASIH BANYAK! Senar dipisahkan oleh "," dan semuanya memiliki "[]" di sekitarnya, yang baik untuk saya.
John Henckel

5

Hanya untuk tantangan "Saya yang terpendek" , berikut adalah tambang;)

Berulang:

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

Rekursif:

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
Versi rekursif elegan. Pasti akan menggunakannya.
Pete

Versi rekursif mungkin elegan, tetapi tidak efisien untuk array besar (" copyOfRange()").
Ogre Psalm33


4

Beginilah cara saya melakukannya.

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

Alternatif serupa

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

Putaran saya.

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

Apakah Anda suka cara 3-baris saya hanya menggunakan metode kelas String?

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
Itu tidak dimaksudkan untuk menjadi efisien. Gunakan StringBuilderjika Anda memerlukan efisiensi: P
Ryoichiro Oka

0

Untuk mendapatkan "str1, str2" dari "str1", "str2", "":

Stream.of("str1", "str2", "").filter(str -> !str.isEmpty()).collect(Collectors.joining(", ")); 

Anda juga dapat menambahkan cek-nol tambahan


0

Jika Anda menggunakan perpustakaan Java Fungsional dan karena alasan tertentu tidak dapat menggunakan Streaming dari Java 8 (yang mungkin terjadi saat menggunakan plugin Android + Retrolambda), berikut adalah solusi fungsional untuk Anda:

String joinWithSeparator(List<String> items, String separator) {
    return items
            .bind(id -> list(separator, id))
            .drop(1)
            .foldLeft(
                    (result, item) -> result + item,
                    ""
            );
}

Perhatikan bahwa ini bukan pendekatan yang paling efisien, tetapi berhasil untuk daftar kecil.


-1

Saya melakukannya dengan cara ini menggunakan 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(rangkaian string dengan operator plus) mengalahkan seluruh tujuan penggunaan a StringBuilder.
quietmint

Plus, pendekatan ini akan berarti array seperti: {"foo", "bar"} dengan pembatas ":" akan berubah menjadi "foo: bar:"
pioto

-2

Ada teknik tulisan cepat sederhana yang saya gunakan sebagian besar kali ..

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

Ini hanya bekerja dengan pembatas dengan panjang 1 dan membutuhkan 'angka ajaib' (meskipun cukup lokal) jika Anda ingin pembatas dengan panjang yang berbeda.
maiwald

Anda dapat menambahkan beberapa karakter saat menambahkan
Gaurav Adurkar

daripada sekadar: op = op.substring (0, op.length () - ",". length ()); apa masalahnya?
Dennis

-3

java.util.Arrays memiliki metode 'asList'. Bersama dengan java.util.List / ArrayList API ini memberi Anda semua yang Anda butuhkan:;

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
Pertanyaannya adalah bagaimana cara menggabungkan array string dengan pembatas, bukan bagaimana menggabungkan dua array string bersama-sama.
Toolbear
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.