Java: PHP'nin join () gibi diziler için işlev?


Yanıtlar:


307

Java8'den başlayarak kullanmak mümkündür String.join().

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

üretir:

Hello, World, !

Aksi takdirde, Apache Commons Lang , dizileri birleştirmek için dizileri birleştirecek StringUtilsbir joinişlevi olan bir sınıfa sahiptir String.

Örneğin:

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

Aşağıdakileri üretir String:

Hello, World, !

7
Bu cevabı arayan kişilerin yararı için, bunun aynı zamanda bir Perl birleştirmesine de eşdeğer olduğuna dikkat edilmelidir.
k-den

3
Benim için tanımsız olduğunu söylüyor
Ninjaxor

@Ninjaxor 1. commons-lang * kavanoz sınıf yolunda olmalıdır 2. import org.apache.commons.lang3.StringUtils;
peterh - Monica'yı geri yükle

9
String.join()Java 8'de sunulan yeni yönteme referans eklemek için bu yanıtı düzenlemenizi tavsiye ederim . Bu şekilde, bu kabul edilen yanıtı okuyan çok sayıda insan bu bilgiden faydalanacaktır. Şu anda, bu gerçeği söyleyen en yüksek oy alan cevap aşağıda oldukça kayboluyor ...
Duncan Jones

1
Sadece veya elemanlar String.join()için işe yarayacağını belirtmek gerekir . List<CharSequence>CharSequence[]
Enigo

71

Android'de ne kullanacağınızı arıyorsanız, bu:

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

Örneğin:

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

2
Java 8 sadece Android'de biraz çıktığı için bu, tüm Android sürümleri için en iyi cevaptır. Bu çözüm, bu aptal yerine "tek bir eylem gerçekleştirmek için büyük bir lib içerir" çözümleri yerleşik Android kütüphanelerini kullanır.
LukeStoneHm

Eylül 2017, Android için Java 8 hala çok uzakta. Bu cevap için teşekkürler!
Aenadon


53

Böyle bir işlevi yaklaşık on kod satırına kolayca yazabilirsiniz:

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
Size göre iyi uygulama ... böyle şeyler için evrensel bir standart yoktur.
phoebus

24
Ama parantez ekleseydim, bu iki kod satırı daha eklerdi ve 11 satırda bunu iddia edemezdim!
Jay

8
sorun, bir süre sonra veya acele başka biri, parantez eklemeden / için başka bir satır eklemek; veya eğer bazı durumlarda derlenirse ancak yanlış olursa (n = k 0) sonra null değerini silin. O zaman bu kapanış ayracı için fazladan bir satır feda etmek daha iyidir (açıklık satır için / satırında aynı kalabilir).
milan

16
Çoğu dilin böyle bir işlevi çekirdeklerine yerleştirmesine rağmen, Java topluluğunun herkesi tekerleği yeniden keşfetmeye teşvik etmesi harika bir şey.
John Strickler

33
11 satır mı? Bah! 1'de yapabilirim! Kaynak dosyadaki tüm yeni satır karakterlerini kaldırmanız yeterlidir.
Thomas Eding

25

Substring () kullanmak yerine küçük bir 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();
}

Herhangi bir kütüphane eklemenize gerek olmadığı için oy verdik.
givanse

10
Satır 7: Bunları birleştirmek yerine .append()her biri için iki kez kullanılır Stringve daha sonra üreticiye eklenirse daha iyi olur .
Talha Ahmed Khan

18

Son zamanlarda birçok soruda olduğu gibi, Java 8 kurtarmaya:


Java 8 java.lang.String, tam olarak istediğinizi yapan yeni bir statik yöntem ekledi :

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

Kullanma:

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

Sonuçlar:

"Hello, World, !"

14

Google guava'nın kütüphanesinde de bu tür bir yetenek vardır . String [] örneğini API'den de görebilirsiniz.

Api'de daha önce açıklandığı gibi, oluşturucu yöntemlerin değişmezliğine dikkat edin.

Bir nesne dizisini kabul edebilir, böylece sizin durumunuzda çalışır. Önceki deneyimlerime göre, bir yinelenebilir bir yığın katılmaya çalıştım ve iyi çalışıyor.

Benden örnek:

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

çıktılar: |i am a coder|


9

Verilen:

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

Daha sonra, yapıştırıcının "," olduğu coobird cevabına alternatif olarak:

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

Veya "& amp;" gibi farklı bir dizeyle birleştirmek için.

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

Ancak ... bu SADECE dizi veya listedeki değerlerin "," karakter dizesini İÇERMEDİĞİNİ biliyorsanız çalışır.


Arrays.asList(a).toString()ne yapmak istediğim için çalıştı
Solomon Ucko

9

Spring Framework kullanıyorsanız, o zaman StringUtils sınıfına sahipsiniz :

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

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

8

Özünde değil, hayır. "Java dizi birleştirme dizesi tutkal" için bir arama size bunu nasıl olsa bazı kod parçacıkları verecektir.

Örneğin

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
Daha iyi performans için StringBuffer (iş parçacığı için güvenli) yerine StringBuilder (iş parçacığı için güvenli değil) kullanın. Arayüz aynı.
Asaph

2
Bu gelmiş gibi görünüyor snippets.dzone.com/posts/show/91 . Yorumlar çok gelişmiş bir sürüm önermektedir: public static String join (Yinelenebilir <? Nesneyi genişletir> pColl, String separator) {Yineleyici <? Object> oIter öğesini genişletir; if (pColl == null || (! (oIter = pColl.iterator ()) .hasNext ())) "" döndürürse; StringBuilder oBuilder = new StringBuilder (String.valueOf (oIter.next ())); while (oIter.hasNext ()) oBuilder.append (ayırıcı) .append (oIter.next ()); return oBuilder.toString (); }
Quantum7

6

Buraya hızlı bir dizi-dize dönüştürme araması yaptıysanız , Arrays.toString () yöntemini deneyin .

Object[]Geçirilenin bir Dize temsilini oluşturur . Sonuç parantez ( "[]") ile çevrelenir , her öğe String.valueOf(Object)ve aracılığıyla bir String'e dönüştürülür ", ". Dizi ise null, o "null"zaman döndürülür.


ÇOK TEŞEKKÜRLER! Dizeler "," ile ayrılır ve her şeyin etrafında "[]" vardır, bu da benim için iyidir.
John Henckel

5

Sadece "Ben en kısa olanım" meydan okuma için, burada mayın;)

yinelemeli:

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

özyineli:

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
Özyinelemeli versiyon zariftir. Kesinlikle kullanacağım.
Pete

Özyinelemeli sürüm zarif olabilir, ancak büyük diziler için verimsiz olabilir (" copyOfRange()").
Ogre Psalm33


4

Ben böyle yaparım.

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

Benzer bir alternatif

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

Dönüşüm.

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

Yalnızca String sınıfının yöntemlerini kullanarak 3 satırlı yolumu beğendiniz mi?

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
Etkili olmak demek değildir. StringBuilderVerimliliğe ihtiyacınız varsa kullanın : P
Ryoichiro Oka

0

"Str1", "str2", "" öğelerinden "str1, str2" almak için:

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

Ayrıca ekstra boş kontrol ekleyebilirsiniz


0

İşlevsel Java kitaplığını kullanıyorsanız ve herhangi bir nedenle Java 8'den Akışları kullanamıyorsanız (Android + Retrolambda eklentisini kullanırken durum böyle olabilir), işte size uygun bir çözüm:

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

En etkili yaklaşım olmadığını, ancak küçük listeler için iyi çalıştığını unutmayın.


-1

Bir StringBuilder kullanarak bu şekilde yaparım:

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(artı işleci ile dize birleştirme) a StringBuilder.
quietmint

Ayrıca, bu yaklaşım, ":" ayırıcılı {"foo", "bar"} gibi bir dizinin "foo: bar:"
biçimine dönüştürüleceği anlamına gelir

-2

Çoğu zaman kullandığım basit stenografi tekniği var ..

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

Bu sadece 1 uzunluğundaki sınırlayıcılarla çalışır ve farklı uzunlukta bir sınırlayıcı istiyorsanız 'sihirli sayılar' (oldukça yerel olsa da) gerektirir.
maiwald


basitçe şunu yapın: op = op.substring (0, op.length () - ",". length ()); sorun ne?
Dennis

-3

java.util.Arrays 'asList' yöntemine sahiptir. Java.util.List / ArrayList API ile birlikte size ihtiyacınız olan her şeyi sunar :;

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
Soru, dizelerin iki dizisini birbirine nasıl birleştireceğinizi değil, bir dizgiyi ayırıcıyla nasıl birleştireceğinizdir.
toolbear
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.