วิธีที่ดีที่สุดในการแปลง ArrayList เป็นสตริง


353

ฉันมีสิ่งArrayListที่ฉันต้องการที่จะส่งออกอย่างสมบูรณ์เป็นสตริง เป็นหลักฉันต้องการที่จะส่งออกเพื่อใช้toStringองค์ประกอบของแต่ละคั่นด้วยแท็บ มีวิธีที่รวดเร็วในการทำเช่นนี้? คุณสามารถวนรอบมัน (หรือลบแต่ละองค์ประกอบ) และเชื่อมต่อกับ String แต่ฉันคิดว่ามันจะช้ามาก


4
หรือลบแต่ละองค์ประกอบระวังด้วยการลบองค์ประกอบออกจากรายการ ArrayList เป็น NO-NO ขนาดใหญ่เนื่องจาก "ลูป" ของคุณจะใช้เวลากำลังสองเนื่องจากการเลื่อนองค์ประกอบ (โดยที่คุณวนลูปจากองค์ประกอบแรกถึงสุดท้าย)
Dimitry K

สำหรับคอลเลคชั่นเดียวกัน: stackoverflow.com/questions/395401/…
Ciro Santilli 法轮功冠状病病六四事件法轮功

คำตอบ:


329

โดยพื้นฐานแล้วการใช้การวนซ้ำเพื่อวนซ้ำArrayListเป็นตัวเลือกเดียว:

อย่าใช้รหัสนี้อ่านต่อไปที่ด้านล่างของคำตอบนี้เพื่อดูว่าทำไมมันจึงไม่เป็นที่ต้องการและควรใช้รหัสใดแทน:

ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

String listString = "";

for (String s : list)
{
    listString += s + "\t";
}

System.out.println(listString);

ในความเป็นจริงการต่อสตริงเป็นไปได้ดีเนื่องจากjavacคอมไพเลอร์จะปรับการต่อสตริงให้เหมาะสมเป็นชุดของappendการดำเนินการStringBuilderต่อไป นี่เป็นส่วนหนึ่งของการแยกส่วนของ bytecode จากforลูปจากโปรแกรมด้านบน:

   61:  new #13; //class java/lang/StringBuilder
   64:  dup
   65:  invokespecial   #14; //Method java/lang/StringBuilder."<init>":()V
   68:  aload_2
   69:  invokevirtual   #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   72:  aload   4
   74:  invokevirtual   #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   77:  ldc #16; //String \t
   79:  invokevirtual   #15; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   82:  invokevirtual   #17; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;

ดังที่สามารถเห็นได้คอมไพเลอร์ปรับห่วงให้เหมาะสมโดยใช้ a StringBuilderดังนั้นประสิทธิภาพจึงไม่ควรเป็นเรื่องใหญ่

(ตกลงในทันทีที่สองStringBuilderจะถูกสร้างอินสแตนซ์ในแต่ละรอบของการวนซ้ำดังนั้นมันอาจไม่ได้เป็น bytecode ที่มีประสิทธิภาพมากที่สุดการใช้อินสแตนซ์และการใช้อย่างชัดเจนStringBuilderอาจทำให้ประสิทธิภาพดีขึ้น)

ในความเป็นจริงฉันคิดว่าการมีเอาต์พุตประเภทใด (ไม่ว่าจะเป็นดิสก์หรือหน้าจอ) อย่างน้อยจะมีลำดับความสำคัญช้ากว่าไม่ต้องกังวลเกี่ยวกับประสิทธิภาพของการต่อสตริง

แก้ไข:ตามที่ระบุไว้ในความคิดเห็นการเพิ่มประสิทธิภาพคอมไพเลอร์ข้างต้นเป็นการสร้างตัวอย่างใหม่ของStringBuilderการทำซ้ำแต่ละครั้ง (ซึ่งฉันได้ระบุไว้ก่อนหน้านี้)

เทคนิคที่เหมาะสมที่สุดที่จะใช้คือการตอบสนองของPaul Tomblinเนื่องจากเป็นเพียงการยกตัวอย่างStringBuilderวัตถุเดียวนอกforลูป

เขียนใหม่เป็นรหัสด้านบนเพื่อ:

ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

StringBuilder sb = new StringBuilder();
for (String s : list)
{
    sb.append(s);
    sb.append("\t");
}

System.out.println(sb.toString());

จะสร้างอินสแตนซ์StringBuilderนอกของลูปเพียงครั้งเดียวและทำการโทรทั้งสองไปยังappendเมธอดภายในลูปตามที่ปรากฏในรหัสไบต์นี้ (ซึ่งแสดงการสร้างอินสแตนซ์ของStringBuilderและลูป):

   // Instantiation of the StringBuilder outside loop:
   33:  new #8; //class java/lang/StringBuilder
   36:  dup
   37:  invokespecial   #9; //Method java/lang/StringBuilder."<init>":()V
   40:  astore_2

   // [snip a few lines for initializing the loop]
   // Loading the StringBuilder inside the loop, then append:
   66:  aload_2
   67:  aload   4
   69:  invokevirtual   #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   72:  pop
   73:  aload_2
   74:  ldc #15; //String \t
   76:  invokevirtual   #14; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   79:  pop

ดังนั้นการเพิ่มประสิทธิภาพของมือควรมีประสิทธิภาพดีกว่าเนื่องจากภายในของforลูปนั้นสั้นกว่าและไม่จำเป็นต้องสร้างอินสแตนซ์ของการStringBuilderวนซ้ำในแต่ละครั้ง


8
ลองใช้คลาส StringBuilder แทนการต่อท้ายสตริงเพื่อเหตุผลด้านประสิทธิภาพ
Jeremy

5
คอมไพเลอร์จะปรับการเรียงสตริงให้เหมาะสม แต่คุณจะสร้างออบเจ็กต์ StringBuilder ใหม่ทุกครั้งที่ลูปถูกเรียกใช้งาน
เปโดร Henriques

4
-1 สำหรับการใช้ + = ในกรณีนี้มันคือ killer killer Performance ใช้ StringBuilder เสมอเพื่อต่อท้ายสตริงซ้ำ
starblue

10
วิธีนี้จะเพิ่ม "\ t" ที่ส่วนท้ายของสตริงซึ่งมักไม่ต้องการโดยเฉพาะเมื่อคุณต้องการสร้างรายการที่คั่นด้วยเครื่องหมายจุลภาคหรือคล้ายกัน ฉันคิดว่าโซลูชันอื่น ๆ ที่โพสต์ที่นี่โดยใช้ Apache Commons หรือ Guava นั้นเหนือกว่า
Peter Goetz

3
นี่ไม่ใช่คำตอบที่ดีที่สุด ดูด้านล่างที่ Vitalii สำหรับJavaหรือ Geewax สำหรับAndroid
Gibolt

895

ใน Java 8 หรือใหม่กว่า:

String listString = String.join(", ", list);

ในกรณีที่listไม่ได้เป็นประเภทของสตริงตัวรวบรวมการเข้าร่วมสามารถใช้:

String listString = list.stream().map(Object::toString)
                        .collect(Collectors.joining(", "));

144
ฉันไม่อยากจะเชื่อเลยว่าจะต้องใช้เวลาจนกว่า Java 8 จะเพิ่มสิ่งนี้
พอล

45
คำตอบนี้ควรได้รับการโหวตมากขึ้น! ไม่มีแฮ็คไม่มีห้องสมุด & ไม่มีลูป
Songo

4
สิ่งนี้ใช้ไม่ได้กับสิ่งที่ OP พูด String.join ใช้เวลาเป็นอาร์กิวเมนต์ที่สอง Iterable <? ขยาย CharSequence> ดังนั้นจึงใช้งานได้หากคุณมี List <String> ที่คุณต้องการแสดง แต่ถ้าคุณมี List <MyObject> มันจะไม่เรียก toString () ตามที่ต้องการโดย OP
Hilikus

3
ทำไมนรกนี่ไม่ใช่คำตอบแรก (และยอมรับ) .. ฉันต้องเลื่อนลงไปเรื่อย ๆ จนกว่าฉันจะรู้ว่ามันมี .. สง่างามและกระชับ
แจ็ค

2
ต้องใช้ Android API 26+
Arsen Sench

391

หากคุณกำลังทำสิ่งนี้บน Android มียูทิลิตีที่ดีสำหรับTextUtilsนี้ซึ่งมี.join(String delimiter, Iterable)วิธีการ

List<String> list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
String joined = TextUtils.join(", ", list);

เห็นได้ชัดว่าไม่ค่อยมีการใช้นอก Android แต่คิดว่าฉันจะเพิ่มลงในเธรดนี้ ...


1
ตั้งแต่TextUtils.joinรับObject[]ฉันจะถือว่ามันเรียกtoString()โทเค็นแต่ละอัน ไม่PatientDetailsดำเนินการtoString()? หากยังไม่สามารถแก้ปัญหาได้คุณอาจติดบางสิ่งบางอย่างกับSeparatorชั้นเรียน
JJ Geewax

5
org.apache.lang3.StringUtilsไม่จริงเดียวกันดังนั้นคำตอบของคุณเป็นอย่างมากในการใช้กับผมด้านนอกของ Android :)
แพทริค

1
ความนิยมของคำตอบนี้ (ปัจจุบันได้รับการโหวตสูงสุด) แสดงให้คุณเห็นว่าคำถามจาวามากมายเกิดขึ้นจากการพัฒนา Android
Amr H. Abd Elmajeed

1
ฉันสามารถเดิมพันที่คุณถูกส่งไปยังโลกนี้เพื่อแก้ปัญหาของฉัน :)
kofoworola

1
คุณช่วยชีวิตฉัน. <3
Pratik Butani

234

ดาวน์โหลด Apache Commons Lang และใช้วิธีการ

 StringUtils.join(list)

 StringUtils.join(list, ", ") // 2nd param is the separator.

คุณสามารถติดตั้งได้ด้วยตัวเองแน่นอน แต่รหัสของพวกเขาได้รับการทดสอบอย่างสมบูรณ์และอาจเป็นการใช้งานที่ดีที่สุด

ฉันเป็นแฟนตัวยงของห้องสมุด Apache Commons และฉันก็คิดว่ามันเป็นส่วนเสริมที่ยอดเยี่ยมของ Java Standard Library


63
น่าเสียดายที่พลเมืองของ SO ต้องการสร้างล้อ
skaffman

33
นอกจากนี้ใน Apache Commons Lang การใช้งานจะมีลักษณะเช่นStringUtils.join(list.toArray(),"\t")
Muhd

33
วงล้อเฉพาะนี้แทบจะไม่คุ้มค่าที่จะต้องพึ่งอะไรเป็นพิเศษ
Seva Alekseyev

25
@SevaAlekseyev ฉันคิดว่ามันเป็นปัญหา หากคุณเพิ่มการพึ่งพานี้ทันทีคุณจะใช้ประโยชน์จากคลาสของมันบ่อยกว่าไม่ แทนที่จะใช้ "if string! = null && string.trim ()! =" "คุณจะใช้ StringUtils.isNotEmpty ... คุณจะใช้ ObjectUtils.equals () เพื่อให้คุณไม่ต้องตรวจสอบ null ทุกที่ แต่ หากคุณรอการพึ่งพาที่ทำให้การใช้ไลบรารีเหล่านี้เป็นจริงคุณอาจไม่เคยใช้มันจริงๆ
Ravi Wallau

6
นอกจากนี้ยังเป็นเรื่องดีที่จะไม่เพิ่มแท็บเพิ่มเติมในตอนท้าย!
keuleJ

139

นี่เป็นคำถามที่ค่อนข้างเก่า แต่ฉันคิดว่าฉันอาจจะเพิ่มคำตอบที่ทันสมัยกว่าเดิม - ใช้JoinerคลาสจากGuava :

String joined = Joiner.on("\t").join(list);

2
นี่คือทางออกที่ฉันโปรดปราน : -> +1 สำหรับฝรั่ง
csgeek

Ctrl + F สำหรับ Guava เช่นกัน ขอบคุณ!
Priidu Neemre

รายการ <String> list = new ArrayList <String> (); list.add ( "Hello"); list.add ( "ไห่"); list.add ( "สวัสดี"); System.out.println (list.toString (). substring (1, list.toString (). length () - 1) .replaceAll (",", "\ t"));
Lova Chittumuri

86

การเปลี่ยนรายการเป็นสตริงที่อ่านได้และมีความหมายเป็นคำถามทั่วไปที่ทุกคนอาจพบ

กรณีที่ 1 หากคุณมี StringUtils ของ Apache ในเส้นทางคลาสของคุณ (จาก rogerdpack และ Ravi Wallau):

import org.apache.commons.lang3.StringUtils;
String str = StringUtils.join(myList);

กรณีที่ 2 หากคุณต้องการใช้วิธีต่าง ๆ จาก JDK (7):

import java.util.Arrays;
String str = Arrays.toString(myList.toArray()); 

อย่าสร้างวงล้อด้วยตัวเองอย่าใช้ลูปสำหรับงานบรรทัดเดียวนี้


1
ฉันไม่ได้สังเกตเห็นโซลูชัน Case 2 ของคุณก่อนโพสต์ของฉันเอง ของคุณดีกว่าจริง ๆ และประหยัดขั้นตอนพิเศษ ฉันอยากจะแนะนำมากกว่าคำตอบบางอย่างที่ดูเหมือนว่าต้องใช้เครื่องมือเพิ่มเติม
Elliander

5
Arrays.toString(myList.toArray())- ทางออกที่ง่ายที่สุดและตรงไปตรงมาที่สุด
Ondrej Bozek

ฉันคิดว่านี่น่าจะถือว่าเป็นทางออกที่ดีที่สุดและมีประสิทธิภาพมากที่สุด
Morey

Arrays.toString(list.toArray())เขียนง่าย แต่ไม่มีประสิทธิภาพสูง
Matthieu

60

หากคุณกำลังมองหาหนึ่งซับด่วนในฐานะของ Java 5 คุณสามารถทำได้:

myList.toString().replaceAll("\\[|\\]", "").replaceAll(", ","\t")

นอกจากนี้หากวัตถุประสงค์ของคุณเพียงเพื่อพิมพ์เนื้อหาและไม่เกี่ยวข้องกับ "\ t" คุณสามารถทำได้ดังนี้:

myList.toString()

ซึ่งส่งกลับสตริงเหมือน

[str1, str2, str3]

หากคุณมี Array (ไม่ใช่ ArrayList) คุณสามารถทำเช่นนี้ได้:

 Arrays.toString(myList).replaceAll("\\[|\\]", "").replaceAll(", ","\t")

3
ฉันคิดว่านี่เป็นวิธีที่มีประสิทธิภาพมากกว่าที่โพสต์ไว้ด้านบน น่าเสียดายที่มันแสดงอยู่ที่ด้านล่าง อาจไม่สวยงาม แต่ฉันเชื่อมั่นอย่างยิ่งว่าโซลูชันของคุณรัน O (n) ในขณะที่ทฤษฎีอื่นรันใน O (n ^ 2) (เนื่องจาก Java Strings ไม่เปลี่ยนรูปคุณจึงสร้าง String ใหม่ในทุก ๆ การผสานและมันแย่ลงเมื่อ ส่งผลให้สตริงกลายเป็นขนาดใหญ่)
3790827

หากข้อความของคุณมีขนาดใหญ่มากคุณจะกินทรัพยากรคอมพิวเตอร์ของคุณ
3790827

วิธีนี้ช้ากว่าการใช้ StringBuilder 7-8 เท่า
Zoka

@ user3790827 คุณกำลังมองหาระดับตื้น ๆ ถ้าฉันบอกให้คุณค้นหาคนในmครัวเรือนในnเมืองต่างๆในxอเมริกาคุณอาจพูดว่าเป็นO(mnx)หรือO(n^3)แต่ฉันสามารถใช้ถ้อยคำใหม่เพื่อพูดว่า "มองหาคนในประเทศนี้" และคุณจะบอกฉันO(n)ทันที ยิ่งไปกว่านั้นอัลกอริธึมทั้งหมดที่นี่โดยทั่วไปO(n)ไม่มีลูปภายในลูป
ใจ

39

วนซ้ำผ่านมันและเรียก toString ไม่มีทางเวทย์มนตร์และถ้ามีคุณคิดว่ามันจะทำอะไรภายใต้ฝาครอบนอกเหนือจากการวนลูปผ่าน? เกี่ยวกับการปรับให้เหมาะสมแบบ micro เพียงอย่างเดียวคือการใช้ StringBuilder แทนที่จะเป็น String และนั่นไม่ใช่การชนะที่ยิ่งใหญ่ - การต่อสตริงกลายเป็น StringBuilder ภายใต้ฝาครอบ แต่อย่างน้อยถ้าคุณเขียนแบบนั้นคุณจะเห็นว่าเกิดอะไรขึ้น

StringBuilder out = new StringBuilder();
for (Object o : list)
{
  out.append(o.toString());
  out.append("\t");
}
return out.toString();

ขอบคุณ! นี้คือสิ่งที่ฉันสิ้นสุดการทำ :)
ฆ Besa

4
สำหรับอาร์เรย์ขนาดใหญ่นี่ไม่ใช่การเพิ่มประสิทธิภาพแบบไมโคร การแปลงอัตโนมัติเพื่อใช้ StringBuilder จะทำแยกต่างหากสำหรับการต่อสตริงแต่ละอันซึ่งไม่ได้ช่วยในกรณีของการวนซ้ำ มันก็โอเคถ้าคุณต่อส่วนประกอบจำนวนมากเข้าด้วยกันในนิพจน์เดียว
starblue

1
การใช้ StringBuilder อย่างชัดเจนเป็นเรื่องใหญ่ถ้าคุณกำลังต่อกันสมมุติว่ามี 50,000 สายที่สร้างสตริงผลลัพธ์ ~ 1 MB - มันอาจแตกต่างจาก 1 นาทีเมื่อเทียบกับเวลาดำเนินการ 1 วินาที
นาย Napik

36

โครงการ Java ส่วนใหญ่มักจะมี apache-commons lang อยู่ วิธีการ StringUtils.join () เป็นสิ่งที่ดีมากและมีหลายรสชาติเพื่อตอบสนองเกือบทุกความต้องการ

public static java.lang.String join(java.util.Collection collection,
                                    char separator)


public static String join(Iterator iterator, String separator) {
    // handle null, zero and one elements before building a buffer 
    Object first = iterator.next();
    if (!iterator.hasNext()) {
        return ObjectUtils.toString(first);
    }
    // two or more elements 
    StringBuffer buf = 
        new StringBuffer(256); // Java default is 16, probably too small 
    if (first != null) {
        buf.append(first);
    }
    while (iterator.hasNext()) {
        if (separator != null) {
            buf.append(separator);
        }
        Object obj = iterator.next();
        if (obj != null) {
            buf.append(obj);
        }
    }
    return buf.toString();
}

พารามิเตอร์:

collection - ชุดของค่าที่จะรวมเข้าด้วยกันอาจเป็นโมฆะ

separator - ตัวคั่นที่จะใช้

คืนค่า : สตริงที่เข้าร่วม, null ถ้าอินพุตตัววนซ้ำเป็นโมฆะ

ตั้งแต่: 2.3


2
นี่เป็นสิ่งที่ดีมากเนื่องจากjoin(...)วิธีนี้มีทั้งชุดข้อมูลและคอลเลกชัน
vikingsteve

ฉันต้องการสร้างคอลเลกชันของสตริงที่มีองค์ประกอบที่มีประชากรไม่ค่อยมีจำนวนสุ่ม ในตอนท้ายฉันต้องการสตริงไม่ใช่อาร์เรย์ไม่ใช่อาร์เรย์เป็นสตริง นี่คือรหัสของฉัน: Collections.shuffle (L); StringBuilder sb = new StringBuilder (); L.forEach (e -> sb.append (e)); ส่งคืน sb.toString ();
dobrivoje


14

สำหรับกรณีการใช้งานที่เรียบง่ายนี้คุณสามารถเข้าร่วมสตริงด้วยเครื่องหมายจุลภาค หากคุณใช้ Java 8:

String csv = String.join("\t", yourArray);

มิฉะนั้นคอมมอนส์ lang มีวิธีการเข้าร่วม ():

String csv = org.apache.commons.lang3.StringUtils.join(yourArray, "\t");

13

วิธีที่สวยงามในการจัดการกับอักขระการแยกต่อท้ายคือการใช้ตัวแยกคลาส

StringBuilder buf = new StringBuilder();
Separator sep = new Separator("\t");
for (String each: list) buf.append(sep).append(each);
String s = buf.toString();

เมธอด toString ของตัวแยกคลาสส่งคืนตัวคั่นยกเว้นสำหรับการโทรครั้งแรก ดังนั้นเราจึงพิมพ์รายการโดยไม่มีตัวคั่นลำดับชั้นนำ (หรือในกรณีนี้)


8

ใน Java 8 นั้นง่ายมาก ดูตัวอย่างสำหรับรายการจำนวนเต็ม:

String result = Arrays.asList(1,2,3).stream().map(Object::toString).reduce((t, u) -> t + "\t" + u).orElse("");

หรือรุ่นหลายบรรทัด (ซึ่งอ่านง่ายกว่า):

String result = Arrays.asList(1,2,3).stream()
    .map(Object::toString)
    .reduce((t, u) -> t + "\t" + u)
    .orElse("");

อัปเดต - เวอร์ชันที่สั้นกว่า

String result = Arrays.asList(1,2,3).stream()
                .map(Object::toString)
                .collect(Collectors.joining("\t"));

2
นี่อาจเป็นเพียงโค้ดหนึ่งบรรทัด แต่สำหรับฉันที่ไม่ได้ดูเรียบง่าย สำหรับฉันการสำรวจรายการและการแยกวิเคราะห์องค์ประกอบลงในสตริงนั้นง่ายกว่านี้
Bartzilla

1
นี่เป็นความประทับใจแรกของฉันเช่นกัน แต่หลังจากที่ฉันคุ้นเคยกับมันฉันพบว่ามันยอดเยี่ยม filterตัวอย่างเช่นคุณสามารถเพิ่มการดำเนินงานเช่น ในที่สุดมันง่ายกว่ามากสำหรับฉันที่จะอ่านรหัส
58

3
ใน Java 8: String.join ("\ t", อาร์เรย์)
Tomasz

ความคิดเห็นล่าสุดใช้งานได้เฉพาะในกรณีที่เนื้อหาเป็นStringเช่นกัน หากเป็นรายการIntegerคุณมีปัญหา
LeO

ทั้งสามตัวนั้นต้องการ API ระดับ 24 บน Android
Asad35Waheed

6

มันเป็นO(n)อัลกอริทึมอย่างใดอย่างหนึ่ง (เว้นแต่คุณจะได้แก้ปัญหาแบบมัลติเธรดที่คุณแบ่งรายการเป็นหลายรายการย่อย แต่ฉันไม่คิดว่าเป็นสิ่งที่คุณขอ)

เพียงใช้StringBuilderดังต่อไปนี้:

StringBuilder sb = new StringBuilder();

for (Object obj : list) {
  sb.append(obj.toString());
  sb.append("\t");
}

String finalString = sb.toString();

StringBuilderจะมากเร็วกว่าสตริงเพราะคุณจะไม่เป็นอีก instantiating Stringวัตถุในแต่ละเรียงต่อกัน


5

ในกรณีที่คุณใช้งานบน Android และคุณยังไม่ได้ใช้แจ็ค (เช่นเพราะมันยังขาดการสนับสนุนสำหรับการใช้งานในทันที) และหากคุณต้องการควบคุมการจัดรูปแบบของสตริงผลลัพธ์มากขึ้น (เช่นคุณต้องการใช้อักขระบรรทัดใหม่เป็น ตัวแบ่งองค์ประกอบ) และเกิดการใช้ / ต้องการใช้ไลบรารี StreamSupport (สำหรับการใช้กระแสข้อมูลบน Java 7 หรือรุ่นก่อนหน้าของคอมไพเลอร์) คุณสามารถใช้สิ่งนี้ (ฉันใส่วิธีนี้ในชั้น ListUtils ของฉัน):

public static <T> String asString(List<T> list) {
    return StreamSupport.stream(list)
            .map(Object::toString)
            .collect(Collectors.joining("\n"));
}

และแน่นอนให้แน่ใจว่าได้ติดตั้ง toString () ในคลาสรายการวัตถุของคุณ


1
การใช้reduceไม่มีประสิทธิภาพอย่างยิ่งสำหรับการต่อข้อมูลสตริง คุณควรจะทำวิธี Java 8 ซึ่งภายในใช้return StreamSupport.stream(list).map(Object::toString).collect(joining("\n")) StringJoinerไม่มีเหตุผลที่คุณไม่สามารถทำสิ่งนี้กับสตรีมการสนับสนุนได้
Stefan Zobel

อีกสิ่งหนึ่งคือรหัสของคุณอาจล้มเหลวอย่างน่ากลัว (เนื่องจากOptional#get) หากผ่านรายการว่างเปล่า
Stefan Zobel

@StefanZobel ขอบคุณสำหรับการชี้ให้เห็นถึงประสิทธิภาพและปัญหาของเคส แก้ไขรหัส
Javad Sadeqzadeh

3

หากคุณไม่ต้องการ \ t หลังองค์ประกอบสุดท้ายคุณต้องใช้ดัชนีเพื่อตรวจสอบ แต่โปรดจำไว้ว่า "ใช้งานได้" เท่านั้น (เช่น O (n)) เมื่อรายการดำเนินการ RandomAccess

List<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

StringBuilder sb = new StringBuilder(list.size() * apprAvg); // every apprAvg > 1 is better than none
for (int i = 0; i < list.size(); i++) {
    sb.append(list.get(i));
    if (i < list.size() - 1) {
        sb.append("\t");
    }
}
System.out.println(sb.toString());

3

รหัสด้านล่างอาจช่วยคุณได้

List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
String str = list.toString();
System.out.println("Step-1 : " + str);
str = str.replaceAll("[\\[\\]]", "");
System.out.println("Step-2 : " + str);

เอาท์พุท:

Step-1 : [1, 2, 3]
Step-2 : 1, 2, 3

3

อาจไม่ใช่วิธีที่ดีที่สุด แต่เป็นวิธีที่สง่างาม

Arrays.deepToString (Arrays.asList ("ทดสอบ", "Test2")

import java.util.Arrays;

    public class Test {
        public static void main(String[] args) {
            System.out.println(Arrays.deepToString(Arrays.asList("Test", "Test2").toArray()));
        }
    }

เอาท์พุต

[ทดสอบทดสอบ 2]


1
ฉันคิดว่านี่เป็นวิธีที่ดีที่สุดถ้า "ดีที่สุด" หมายถึงการอ่านรหัสได้ ฉันไม่ได้ดูรหัส แต่อาจมีประสิทธิภาพเท่ากับวิธีการ StringBuilder (อาจใช้ StringBuilder ใต้กระโปรงหน้ารถ) แม้ว่าจะไม่สามารถปรับแต่งได้ในผลลัพธ์
Mike Miller

3

ต่อไปนี้จะเป็นสิ่งที่ดีหรือไม่:

List<String> streamValues = new ArrayList<>();
Arrays.deepToString(streamValues.toArray()));   

3

หากคุณใช้Eclipse Collectionsคุณสามารถใช้makeString()วิธีนี้ได้

ArrayList<String> list = new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");

Assert.assertEquals(
    "one\ttwo\tthree",
    ArrayListAdapter.adapt(list).makeString("\t"));

หากคุณสามารถแปลงArrayListเป็น a FastListคุณสามารถกำจัดอะแดปเตอร์

Assert.assertEquals(
    "one\ttwo\tthree",
    FastList.newListWith("one", "two", "three").makeString("\t"));

หมายเหตุ: ฉันเป็นคอมมิชชันสำหรับ Eclipse Collections


3
List<String> stringList = getMyListOfStrings();
StringJoiner sj = new StringJoiner(" ");
stringList.stream().forEach(e -> sj.add(e));
String spaceSeparated = sj.toString()

คุณส่งผ่านไปยังnew StringJoinerลำดับถ่านที่คุณต้องการใช้เป็นตัวคั่น หากคุณต้องการทำ CSV:new StringJoiner(", ");


3

ในหนึ่งบรรทัด: จาก [12,0,1,78,12] ถึง 12 0 1 78 12

String srt= list.toString().replaceAll("\\[|\\]|,","");

2
1) ไม่มีเหตุผลที่จะใช้รหัสเช่นนี้อีกต่อไป (ณ 4 ปีที่แล้ว!) 2) คำตอบนี้ไม่ได้เพิ่มคำถามใด ๆ
Radiodef

5 ดาวในหนึ่งบรรทัด ขอบคุณมาก.
Atef Farouk

มันทำงานได้อย่างสมบูรณ์แบบ สำหรับสตริงที่คั่นด้วยคอมมาให้ใช้: String srt = list.toString (). replaceAll ("\ [| \]", "");
Asad35Waheed

2

สำหรับการแยกโดยใช้แท็บแทนการใช้printlnคุณสามารถใช้การพิมพ์

ArrayList<String> mylist = new ArrayList<String>();

mylist.add("C Programming");
mylist.add("Java");
mylist.add("C++");
mylist.add("Perl");
mylist.add("Python");

for (String each : mylist)
{       
    System.out.print(each);
    System.out.print("\t");
}

1

ฉันเห็นตัวอย่างค่อนข้างน้อยซึ่งขึ้นอยู่กับทรัพยากรเพิ่มเติม แต่ดูเหมือนว่านี่จะเป็นวิธีแก้ปัญหาที่ง่ายที่สุด: (ซึ่งเป็นสิ่งที่ฉันใช้ในโครงการของฉันเอง) ซึ่งโดยทั่วไปแล้วเพิ่งแปลงจาก ArrayList เป็น ArrayList และเป็น List .

    List<Account> accounts = new ArrayList<>();

   public String accountList() 
   {
      Account[] listingArray = accounts.toArray(new Account[accounts.size()]);
      String listingString = Arrays.toString(listingArray);
      return listingString;
   }

0

นี่เป็นบทสนทนาที่ค่อนข้างเก่าแล้วและตอนนี้ apache คอมมอนส์ใช้ StringBuilder ภายใน: http://commons.apache.org/lang/api/src-html/org/apache/commons/lang/StringUtils.html#line 3045

สิ่งนี้จะเป็นไปตามที่เราทราบว่าปรับปรุงประสิทธิภาพ แต่ถ้าประสิทธิภาพมีความสำคัญดังนั้นวิธีที่ใช้อาจไม่มีประสิทธิภาพ ในขณะที่อินเทอร์เฟซมีความยืดหยุ่นและจะช่วยให้มีพฤติกรรมที่สอดคล้องกันในประเภทคอลเลกชันที่แตกต่างกันซึ่งค่อนข้างไม่มีประสิทธิภาพสำหรับรายการซึ่งเป็นประเภทของคอลเลกชันในคำถามเดิม

ฉันยึดสิ่งนี้ในการที่เรากำลังก่อให้เกิดค่าโสหุ้ยซึ่งเราจะหลีกเลี่ยงได้ง่ายๆโดยการวนซ้ำองค์ประกอบต่างๆในรูปแบบดั้งเดิมสำหรับลูป แต่มีบางสิ่งเพิ่มเติมที่เกิดขึ้นเบื้องหลังการตรวจสอบฉากสำหรับการปรับเปลี่ยนที่เกิดขึ้นพร้อมกัน, การเรียกเมธอดเป็นต้นการปรับปรุงสำหรับลูปจะส่งผลให้ค่าใช้จ่ายเดียวกันเนื่องจากใช้ตัววนซ้ำบนวัตถุ Iterable (รายการ)


0

คุณสามารถใช้ Regex สำหรับสิ่งนี้ นี่คือรัดกุมตามที่ได้รับ

System.out.println(yourArrayList.toString().replaceAll("\\[|\\]|[,][ ]","\t"));

-1

ฟังก์ชั่นนี้เกี่ยวกับ:

public static String toString(final Collection<?> collection) {
    final StringBuilder sb = new StringBuilder("{");
    boolean isFirst = true;
    for (final Object object : collection) {
        if (!isFirst)
            sb.append(',');
        else
            isFirst = false;
        sb.append(object);
    }
    sb.append('}');
    return sb.toString();
}

ใช้งานได้กับคอลเลกชันทุกประเภท ...

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