Java: ฟังก์ชั่นสำหรับอาร์เรย์เช่นการเข้าร่วมของ PHP ()?


259

ฉันต้องการเข้าร่วมString[]กับสายกาว มีฟังก์ชั่นนี้หรือไม่?


7
Java 8 มีฟังก์ชั่นนี้รวมอยู่ในกล่อง ฉันแนะนำให้ผู้อ่านเลื่อนดูคำตอบโดย @Marek Gregor (และโหวตขึ้น .. )
Stav

คำตอบ:


307

เริ่มต้นจากJava8String.join()มันเป็นไปได้ที่จะใช้งาน

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

สร้าง:

Hello, World, !

มิฉะนั้นApache คอมมอนส์แลงมีStringUtilsระดับซึ่งมีฟังก์ชั่นที่จะเข้าร่วมอาร์เรย์ร่วมกันเพื่อให้joinString

ตัวอย่างเช่น:

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

สร้างสิ่งต่อไปนี้String:

Hello, World, !

7
เพื่อประโยชน์ของผู้ที่ค้นหาคำตอบนี้ควรสังเกตว่านี่เป็นสิ่งที่เทียบเท่ากับการเข้าร่วม Perl
k-den

3
มันบอกว่ามันไม่ได้กำหนดสำหรับฉัน
Ninjaxor

@Ninjaxor 1. jar ทั่วไปต้องอยู่ใน classpath 2. นำเข้า org.apache.commons.lang3.StringUtils;
peterh - Reinstate Monica

9
ฉันอยากจะแนะนำให้คุณแก้ไขคำตอบนี้เพื่อเพิ่มการอ้างอิงถึงString.join()วิธีการใหม่ที่แนะนำใน Java 8 ด้วยวิธีนี้ผู้คนจำนวนมากที่อ่านคำตอบที่ยอมรับนี้จะได้รับประโยชน์จากความรู้นั้น ขณะนี้ได้รับการโหวตมากที่สุดคำตอบที่กล่าวขวัญความเป็นจริงนี้จะหายไปค่อนข้างลงมาด้านล่าง ...
ดันแคนโจนส์

1
เป็นมูลค่าการกล่าวขวัญว่าString.join()จะใช้งานได้เฉพาะกับองค์ประกอบList<CharSequence>หรือ CharSequence[]
Enigo

71

หากคุณกำลังมองหาสิ่งที่จะใช้ใน Android มันเป็น:

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

ตัวอย่างเช่น:

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

2
นี่เป็นคำตอบที่ดีที่สุดสำหรับ Android ทุกรุ่นอย่างชัดเจนเนื่องจาก Java 8 ออกมาใน Android เพียงเล็กน้อยเท่านั้น วิธีการแก้ปัญหานี้ใช้ libs Android ในตัวแทนที่จะใช้คำว่า "รวม lib ขนาดใหญ่เพื่อดำเนินการหนึ่งการกระทำ"
LukeStoneHm

ในเดือนกันยายนปี 2017 Java 8 สำหรับ Android ยังคงห่างไกล ขอบคุณสำหรับคำตอบนี้!
Aenadon


53

คุณสามารถเขียนฟังก์ชั่นดังกล่าวได้อย่างง่ายดายในโค้ดประมาณสิบบรรทัด:

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
การฝึกฝนที่ดีตามที่คุณ ... ไม่มีมาตรฐานสากลสำหรับสิ่งต่าง ๆ
phoebus

24
แต่ถ้าฉันใส่เครื่องหมายปีกกานั่นจะเพิ่มโค้ดอีกสองบรรทัดและฉันไม่สามารถอ้างสิทธิ์ได้ใน 11 บรรทัด!
Jay

8
ปัญหาคือเมื่อคุณหลังจากนั้นไม่นานหรือคนอื่นรีบเพิ่มบรรทัดอื่นที่ถ้า / โดยไม่ต้องเพิ่มวงเล็บปีกกา; หรือลบคืนค่า null หลังจากถ้า (k == 0) ซึ่งในบางกรณีจะคอมไพล์ แต่จะไม่ถูกต้อง จากนั้นจะเป็นการดีกว่าที่จะเสียสละหนึ่งบรรทัดสำหรับวงเล็บปีกกานั้น (การเปิดสามารถอยู่ในบรรทัดเดียวกันถ้า / สำหรับบรรทัด)
มิลาน

16
ฉันคิดว่ามันยอดเยี่ยมที่ในขณะที่ภาษาส่วนใหญ่บรรจุฟังก์ชั่นดังกล่าวไว้ในแกนหลักของพวกเขาชุมชน Java สนับสนุนให้ทุกคนคิดค้นนวัตกรรมใหม่
John Strickler

33
11 บรรทัด? Bah! ฉันสามารถทำได้ใน 1! เพียงลบอักขระบรรทัดใหม่ทั้งหมดในไฟล์ต้นฉบับ
Thomas Eding

25

mod เล็กน้อยแทนที่จะใช้ 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();
}

โหวตเนื่องจากคุณไม่จำเป็นต้องเพิ่มห้องสมุดใด ๆ
givanse

10
บรรทัดที่ 7: จะดีกว่าไหมถ้าใช้.append()สองครั้งStringแทนกันต่อกันแล้วต่อท้ายกับตัวสร้าง
Talha Ahmed Khan

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 guava ยังมีความสามารถเช่นนี้ คุณสามารถดูตัวอย่าง String [] ได้จาก API

ดังที่อธิบายไว้แล้วใน API โปรดระวังการเปลี่ยนแปลงของวิธีการสร้าง

มันสามารถรับชุดของวัตถุต่าง ๆ ได้ดังนั้นมันจะทำงานในกรณีของคุณ จากประสบการณ์ครั้งก่อนของฉันฉันพยายามเข้าร่วมกองซ้อนซึ่งเป็น iterable และทำงานได้ดี

ตัวอย่างจากฉัน:

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()ทำงานในสิ่งที่ฉันต้องการจะทำ
โซโลมอนอุ๊กโซ่


8

ไม่ใช่ในแกนไม่ใช่ การค้นหา "จาวาอาร์เรย์เข้าร่วมสตริงกาว" จะให้ตัวอย่างโค้ดบางอย่างเกี่ยวกับวิธีการที่จะบรรลุนี้

เช่น

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
ใช้ StringBuilder (ไม่ใช่เธรดที่ปลอดภัย) แทน StringBuffer (เธรดที่ปลอดภัย) เพื่อประสิทธิภาพที่ดีขึ้น อินเทอร์เฟซเหมือนกัน
Asaph

2
นี้น่าจะเป็นจากsnippets.dzone.com/posts/show/91 ความคิดเห็นแนะนำรุ่นที่ปรับปรุงมาก: การเข้าร่วม String สาธารณะแบบคงที่ (Iterable <? ขยายวัตถุ> pColl, ตัวคั่นสตริง) {Iterator <? ขยายวัตถุ> oIter; if (pColl == null || (! (oIter = pColl.iterator ()) .hasNext ())) return ""; StringBuilder oBuilder = ใหม่ StringBuilder (String.valueOf (oIter.next ())); ในขณะที่ (oIter.hasNext ()) oBuilder.append (ตัวคั่น). ผนวก (oIter.next ()); ส่งคืน oBuilder.toString (); }
Quantum7

6

หากคุณได้ที่ดินที่นี่มองหาแปลงอาร์เรย์กับสตริงอย่างรวดเร็วลองArrays.toString ()

สร้างการเป็นตัวแทนสตริงของการObject[]ส่งผ่าน ผลที่ถูกล้อมรอบด้วยวงเล็บ ( "[]") แต่ละองค์ประกอบจะถูกแปลงเป็นสตริงผ่านและแยกจากกันโดยString.valueOf(Object) ", "ถ้าอาร์เรย์เป็น nullเช่นนั้น"null"จะถูกส่งกลับ


ขอบคุณมาก ๆ! สตริงจะถูกคั่นด้วย "," และทุกสิ่งมี "[]" อยู่รอบ ๆ ซึ่งใช้ได้กับฉัน
John Henckel

5

สำหรับความท้าทาย"ฉันสั้นที่สุด"นี่คือเหมือง;)

ซ้ำ:

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

recursive:

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
เวอร์ชั่นเรียกซ้ำนั้นสง่างาม จะใช้มันอย่างแน่นอน
Pete

เวอร์ชันเรียกซ้ำอาจสง่างาม แต่ไม่มีประสิทธิภาพสำหรับอาร์เรย์ขนาดใหญ่ (" copyOfRange()")
Ogre Psalm33


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

คุณชอบวิธี 3 บรรทัดของฉันโดยใช้วิธีการของคลาส 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
มันไม่ได้หมายความว่ามีประสิทธิภาพ ใช้StringBuilderถ้าคุณต้องการประสิทธิภาพ: P
Ryoichiro Oka

0

วิธีรับ "str1, str2" จาก "str1", "str2", "":

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

นอกจากนี้คุณสามารถเพิ่มการตรวจสอบโมฆะพิเศษ


0

ในกรณีที่คุณใช้ไลบรารี่ Functional Java และด้วยเหตุผลบางอย่างไม่สามารถใช้ Streams จาก Java 8 (ซึ่งอาจเป็นกรณีที่ใช้ปลั๊กอิน 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(concatenation สตริงกับผู้ประกอบการบวก) StringBuilderเอาชนะทั้งวัตถุประสงค์ของการใช้
quietmint

นอกจากนี้วิธีการนี้จะหมายความว่าอาร์เรย์เช่น: {"foo", "bar"} พร้อมตัวคั่น ":" จะกลายเป็น "foo: bar:"
pioto

-2

มีเทคนิคชวเลขง่ายๆที่ฉันใช้บ่อยครั้ง ..

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

สิ่งนี้ใช้ได้กับตัวคั่นความยาว 1 เท่านั้นและต้องใช้ 'หมายเลขเวทมนตร์' (แม้ว่าจะค่อนข้างอยู่ในพื้นที่) หากคุณต้องการตัวคั่นที่มีความยาวต่างกัน
maiwald

คุณสามารถเพิ่มตัวละครหลายตัวในขณะที่ผนวก
Gaurav Adurkar

กว่าทำง่ายๆ: op = op.substring (0, op.length () - ",". length ()); เรื่องใหญ่อะไร
Dennis

-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
คำถามคือวิธีการรวมอาร์เรย์ของสตริงด้วยตัวคั่นไม่ใช่วิธีการรวมสตริงสองอาร์เรย์เข้าด้วยกัน
แถบเครื่องมือ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.