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, !
coobird
sumber
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);
Nuh
sumber
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();
}
Jay
sumber
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();
}
everlasto
sumber
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, !"
icza
sumber
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|

bertie
sumber
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 ",".

Rob di TVSeries.com
sumber
Arrays.asList(a).toString()bekerja untuk apa yang ingin saya lakukan
Solomon Ucko
9

Jika Anda menggunakan Spring Framework maka Anda memiliki kelas StringUtils :

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

arrayToDelimitedString(new String[] {"A", "B", "C"}, "\n");
perbaikan tanpa henti
sumber
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();
}

sumber
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.

tenang
sumber
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)));
}
sp00m
sumber
2
Versi rekursif elegan. Pasti akan menggunakannya.
Pete
Versi rekursif mungkin elegan, tetapi tidak efisien untuk array besar (" copyOfRange()").
Ogre Psalm33
4

Tidak ada built-in yang saya ketahui.

Apache Commons Lang memiliki kelas yang disebut StringUtilsyang berisi banyak fungsi bergabung.

JonMR
sumber
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();
}
Richard Corfield
sumber
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();
}
William Simpson
sumber
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, "");
}
Jackson
sumber
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());
}
Ryoichiro Oka
sumber
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

ema
sumber
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.

Dmitry Zaytsev
sumber
-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)
spanky762
sumber
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);
Gaurav Adurkar
sumber
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]);
}
Adriaan Koster
sumber
7
Pertanyaannya adalah bagaimana cara menggabungkan array string dengan pembatas, bukan bagaimana menggabungkan dua array string bersama-sama.
Toolbear