การแปลงอาร์เรย์เป็นลิสต์ใน Java


1027

ฉันจะแปลงอาร์เรย์เป็นรายการใน Java ได้อย่างไร

ฉันใช้Arrays.asList()แต่พฤติกรรม (และลายเซ็น) เปลี่ยนจาก Java SE 1.4.2 (เอกสารตอนนี้ในที่เก็บถาวร) เป็น8และตัวอย่างข้อมูลส่วนใหญ่ที่ฉันพบบนเว็บใช้พฤติกรรม 1.4.2

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

int[] spam = new int[] { 1, 2, 3 };
Arrays.asList(spam)
  • on 1.4.2 จะส่งคืนรายการที่มีองค์ประกอบ 1, 2, 3
  • on 1.5.0+ ส่งคืนรายการที่มีอาร์เรย์สแปม

ในหลายกรณีมันควรจะตรวจจับได้ง่าย แต่บางครั้งมันอาจไม่มีใครสังเกตเห็น:

Assert.assertTrue(Arrays.asList(spam).indexOf(4) == -1);

20
ฉันคิดว่าตัวอย่างของคุณเสีย: Arrays.asList(new int[] { 1, 2, 3 }); แน่นอนไม่ได้รวบรวมในชวา 1.4.2 เพราะint[]เป็นไม่ Object[]
Joachim Sauer

1
โอ้คุณอาจพูดถูก ฉันไม่มีคอมไพเลอร์ Java 1.4.2 เพื่อทดสอบตัวอย่างก่อนโพสต์ ตอนนี้หลังจากความคิดเห็นของคุณและคำตอบของโจทุกอย่างสมเหตุสมผลมากขึ้น
Alexandru

1
ฉันคิดว่า Autoboxing น่าจะครอบคลุมการแปลงจากแบบดั้งเดิมเป็น wrapper คลาส Integer คุณสามารถทำให้การโยนตัวเองก่อนแล้วรหัสข้างต้นArrays.asListควรจะทำงาน
Horse Voice

2
Stream.boxed ของ Java 8 () จะดูแล autoboxing และสามารถนำไปใช้ในการนี้ได้ ดูคำตอบของฉันด้านล่าง
Ibrahim Arief

คำตอบ:


1430

ในตัวอย่างของคุณเป็นเพราะคุณไม่สามารถมีรายการประเภทดั้งเดิมได้ กล่าวอีกนัยหนึ่งList<int>เป็นไปไม่ได้

อย่างไรก็ตามคุณสามารถList<Integer>ใช้Integerคลาสที่ล้อมรอบintดั้งเดิมได้ แปลงอาร์เรย์ของคุณเป็น a Listด้วยArrays.asListวิธีการยูทิลิตี้

Integer[] spam = new Integer[] { 1, 2, 3 };
List<Integer> list = Arrays.asList(spam);

ดูนี้ใช้รหัสสดที่ IdeOne.com


112
หรือง่ายยิ่งขึ้น: Arrays.asList (1, 2, 3);

45
จะรู้ได้อย่างไรว่าจะไม่สร้างList<Integer[]>?
โทมัส Ahle

25
ล้มเหลวใน Java 5+
djechlin

6
@ThomasAhle มันไม่ได้สร้าง List <Integer []> มันจะสร้าง List <Integer> วัตถุ และถ้าคุณต้องการที่จะพิมพ์ปลอดภัยคุณเขียน: อาร์เรย์ <Integer> asList (สแปม);
user1712376

6
@ThomasAhle นั่นเป็นคำถามที่ดี เดาว่าเป็นเพียงกฎในคอมไพเลอร์ java สำหรับตัวอย่างโค้ดต่อไปนี้จะคืนค่า List <Integer []> Integer[] integerArray1 = { 1 }; Integer[] integerArray2 = { 2 }; List<Integer[]> integerArrays = Arrays.asList(integerArray1, integerArray2);
Simon

167

ใน Java 8 คุณสามารถใช้สตรีม:

int[] spam = new int[] { 1, 2, 3 };
Arrays.stream(spam)
      .boxed()
      .collect(Collectors.toList());

นี้เป็นสิ่งที่ดี boolean[]แต่มันจะไม่ทำงาน Boolean[]ฉันเดาว่าเพราะมันเป็นเพียงเป็นเรื่องง่ายที่จะทำให้ นั่นอาจเป็นทางออกที่ดีกว่า อย่างไรก็ตามมันแปลกที่น่าสนใจ
GlenPeterson

138

Listพูดเกี่ยวกับวิธีการแปลงก็ขึ้นอยู่กับเหตุผลที่คุณไม่จำเป็นต้องของคุณ หากคุณต้องการเพียงแค่อ่านข้อมูล ตกลงไปเลย:

Integer[] values = { 1, 3, 7 };
List<Integer> list = Arrays.asList(values);

แต่ถ้าคุณทำสิ่งนี้:

list.add(1);

java.lang.UnsupportedOperationExceptionคุณจะได้รับ ดังนั้นสำหรับบางกรณีคุณจำเป็นต้องใช้สิ่งนี้:

Integer[] values = { 1, 3, 7 };
List<Integer> list = new ArrayList<Integer>(Arrays.asList(values));

วิธีแรกจริงไม่แปลงอาร์เรย์ แต่ 'หมายถึง' Listมันเหมือน แต่อาร์เรย์อยู่ภายใต้ประทุนพร้อมคุณสมบัติทั้งหมดเช่นจำนวนองค์ประกอบที่แน่นอน ArrayListโปรดทราบคุณจะต้องระบุประเภทเมื่อสร้าง


1
"การเปลี่ยนไม่ได้" ทำให้ฉันสับสนอยู่ครู่หนึ่ง คุณสามารถเปลี่ยนค่าของอาเรย์ได้อย่างชัดเจน อย่างไรก็ตามคุณไม่สามารถเปลี่ยนขนาดได้
Tim Pohlmann

125

ปัญหาคือว่า varargs ได้เปิดตัวใน Java5 และน่าเสียดายที่Arrays.asList()ได้รับมากเกินไปกับรุ่น vararg เกินไป ดังนั้นจึงArrays.asList(spam)เป็นที่เข้าใจกันโดยคอมไพเลอร์ Java5 เป็นพารามิเตอร์ vararg ของ int arrays

ปัญหานี้ได้อธิบายรายละเอียดเพิ่มเติมใน Effective Java 2nd Ed., บทที่ 7, Item 42


4
ฉันเข้าใจสิ่งที่เกิดขึ้น แต่ไม่ใช่เหตุผลที่ไม่มีการบันทึกไว้ ฉันกำลังมองหาโซลูชันทางเลือกโดยไม่ต้องใช้ล้ออีกครั้ง
Alexandru

2
@UsmanIsmail ในฐานะของ Java 8 เราสามารถใช้สตรีมสำหรับการแปลงนี้ ดูคำตอบของฉันด้านล่าง
Ibrahim Arief

109

ดูเหมือนว่าจะสายเล็กน้อย แต่ที่นี่เป็นสองเซ็นต์ของฉัน เราไม่สามารถมีList<int>ฐานะเป็นชนิดดั้งเดิมเพื่อให้เราสามารถมีเพียงintList<Integer>

Java 8 (int array)

int[] ints = new int[] {1,2,3,4,5};
List<Integer> list11 =Arrays.stream(ints).boxed().collect(Collectors.toList()); 

Java 8 และต่ำกว่า (จำนวนเต็ม)

Integer[] integers = new Integer[] {1,2,3,4,5};
List<Integer> list21 =  Arrays.asList(integers); // returns a fixed-size list backed by the specified array.
List<Integer> list22 = new ArrayList<>(Arrays.asList(integers)); // good
List<Integer> list23 = Arrays.stream(integers).collect(Collectors.toList()); //Java 8 only

ต้องการ ArrayList และไม่ใช่ List ใช่หรือไม่

ในกรณีที่เราต้องการใช้งานเฉพาะของListเช่นArrayListนั้นเราสามารถใช้toCollectionเป็น:

ArrayList<Integer> list24 = Arrays.stream(integers)
                          .collect(Collectors.toCollection(ArrayList::new));

ทำไมlist21ไม่สามารถแก้ไขโครงสร้าง

เมื่อเราใช้Arrays.asListขนาดของรายการกลับได้รับการแก้ไขเพราะรายชื่อที่ส่งกลับมาไม่ได้แต่ระดับคงที่ส่วนตัวที่กำหนดไว้ภายในjava.util.ArrayList java.util.Arraysดังนั้นหากเราเพิ่มหรือลบองค์ประกอบออกจากรายการที่ส่งคืนแล้วUnsupportedOperationExceptionจะถูกโยนทิ้ง ดังนั้นเราควรไปด้วยlist22เมื่อเราต้องการแก้ไขรายการ ถ้าเรามี Java8 list23แล้วเรายังสามารถไปกับ

เพื่อความชัดเจนlist21สามารถแก้ไขได้ในแง่ที่เราสามารถเรียกได้list21.set(index,element)แต่รายการนี้อาจไม่ได้รับการปรับเปลี่ยนโครงสร้างเช่นไม่สามารถเพิ่มหรือลบองค์ประกอบออกจากรายการ คุณสามารถตรวจสอบคำถามนี้ได้


ถ้าเราต้องการรายชื่อที่ไม่เปลี่ยนรูปเราก็สามารถสรุปเป็น:

List<Integer> list 22 = Collections.unmodifiableList(Arrays.asList(integers));

อีกประเด็นที่ควรทราบก็คือวิธีนี้Collections.unmodifiableListจะคืนค่ามุมมองที่ไม่สามารถเปลี่ยนแปลงได้ของรายการที่ระบุ คอลเล็กชันมุมมอง unmodifiable คือคอลเล็กชันที่ไม่สามารถแก้ไขได้และเป็นมุมมองไปยังคอลเล็กชันสำรอง โปรดทราบว่าการเปลี่ยนแปลงในคอลเลกชันสำรองอาจยังคงเป็นไปได้และหากเกิดขึ้นพวกเขาจะสามารถมองเห็นได้ผ่านมุมมองที่ไม่สามารถแก้ไขได้

เราสามารถมีรายชื่อไม่เปลี่ยนแปลงอย่างแท้จริงใน Java 9 และ 10

รายการไม่น่าเชื่อถืออย่างแท้จริง

Java 9:

String[] objects = {"Apple", "Ball", "Cat"};
List<String> objectList = List.of(objects);

Java 10 (รายการไม่น่าเชื่อถือที่แท้จริง) ในสองวิธี:

  1. List.copyOf(Arrays.asList(integers))
  2. Arrays.stream(integers).collect(Collectors.toUnmodifiableList());

ตรวจสอบคำตอบของฉันนี้เพิ่มเติม


@BasilBourque ฉันหมายถึงไม่สามารถแก้ไขโครงสร้างของรายการโดยการเพิ่ม / ลบ แต่สามารถเปลี่ยนองค์ประกอบ
akhil_mittal

อันที่จริงผมพยายามรหัสบางอย่างและยืนยันว่าการเรียกList::addและล้มเหลวกับรายการส่งกลับโดยList::remove Arrays.asListJavaDoc สำหรับวิธีการนั้นเขียนได้ไม่ดีและไม่ชัดเจนในจุดนี้ ในการอ่านครั้งที่สามของฉันฉันคิดว่าวลี“ ขนาดคงที่” มีความหมายว่าจะไม่สามารถเพิ่มหรือลบองค์ประกอบได้
Basil Bourque


11

ฉันเพิ่งต้องแปลงอาร์เรย์เป็นรายการ ในภายหลังในโปรแกรมกรองรายการพยายามลบข้อมูล เมื่อคุณใช้ฟังก์ชัน Arrays.asList (array) คุณจะสร้างคอลเลกชันขนาดคงที่: คุณไม่สามารถเพิ่มหรือลบได้ รายการนี้อธิบายถึงปัญหาได้ดีกว่าที่ฉันทำได้: เหตุใดฉันจึงได้รับ UnsupportedOperationException เมื่อพยายามลบองค์ประกอบออกจากรายการ .

ในที่สุดฉันต้องทำการแปลง "ด้วยตนเอง":

    List<ListItem> items = new ArrayList<ListItem>();
    for (ListItem item: itemsArray) {
        items.add(item);
    }

ฉันคิดว่าฉันสามารถเพิ่มการแปลงจากอาร์เรย์ไปยังรายการโดยใช้การดำเนินการ List.addAll (รายการ)


11
new ArrayList<ListItem>(Arrays.asList(itemsArray))จะเหมือนกัน
Marco13

1
@BradyZhu: คำตอบที่ได้รับข้างต้นไม่ได้แก้ปัญหาของฉันด้วยอาร์เรย์ขนาดคงที่ แต่คุณมักจะพูด RTFM ที่นี่ซึ่งเป็นรูปแบบที่ไม่ดีเสมอ โปรดอธิบายสิ่งที่ผิดกับคำตอบหรือไม่ต้องการแสดงความคิดเห็น
Steve Gelman

2
เครื่องมือตรวจสอบอาจแสดงคำเตือนที่นี่และคุณตั้งชื่อเหตุผล ไม่จำเป็นต้องคัดลอกองค์ประกอบด้วยตนเองใช้Collections.addAll(items, itemsArray)แทน
Darek Kay

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

7

ใช้อาร์เรย์

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

Integer[] existingArray = {1, 2, 3};
List<Integer> list1 = Arrays.asList(existingArray);
List<Integer> list2 = Arrays.asList(1, 2, 3);

// WARNING:
list2.add(1);     // Unsupported operation!
list2.remove(1);  // Unsupported operation!

ใช้ ArrayList หรือรายการอื่น ๆ

คุณสามารถใช้การforวนซ้ำเพื่อเพิ่มองค์ประกอบทั้งหมดของอาร์เรย์ในListการนำไปปฏิบัติเช่นArrayList:

List<Integer> list = new ArrayList<>();
for (int i : new int[]{1, 2, 3}) {
  list.add(i);
}

การใช้ Stream API ใน Java 8

คุณสามารถเปลี่ยนอาร์เรย์เป็นสตรีมจากนั้นรวบรวมสตรีมโดยใช้ตัวรวบรวมอื่น: ตัวรวบรวมเริ่มต้นใน Java 8 ใช้ArrayListหลังหน้าจอ แต่คุณสามารถกำหนดการนำไปใช้ที่ต้องการได้

List<Integer> list1, list2, list3;
list1 = Stream.of(1, 2, 3).collect(Collectors.toList());
list2 = Stream.of(1, 2, 3).collect(Collectors.toCollection(ArrayList::new));
list3 = Stream.of(1, 2, 3).collect(Collectors.toCollection(LinkedList::new));

ดูสิ่งนี้ด้วย:



5

คุณต้องเข้าแถว

Arrays.asList((Object[]) array)

3
java: ประเภทที่เข้ากันไม่ได้: int [] ไม่สามารถแปลงเป็น java.lang.Object []
dVaffection

@dVaffection จากนั้นส่งไปยัง int [] ส่วนที่สำคัญคือการส่งอาเรย์
Nebril


5

ใน Java 9 คุณมีวิธีที่ยอดเยี่ยมกว่าในการใช้รายการที่ไม่เปลี่ยนรูปแบบด้วยวิธีการใหม่ที่สะดวกสบายจากโรงงานList.of:

List<String> immutableList = List.of("one","two","three");

(คัดลอกมาจากที่นี่อย่างไร้ยางอาย)


FYI เพื่อเรียนรู้รายละเอียดทางเทคนิคที่อยู่เบื้องหลังสิ่งนี้โปรดดูJEP 269: วิธีการอำนวยความสะดวกในโรงงานสำหรับการสะสมและการพูดคุยโดย Stuart Marksผู้เขียนหลัก
Basil Bourque

5

หากคุณกำหนดเป้าหมายเป็น Java 8 (หรือใหม่กว่า) คุณสามารถลองสิ่งนี้:

int[] numbers = new int[] {1, 2, 3, 4};
List<Integer> integers = Arrays.stream(numbers)
                        .boxed().collect(Collectors.<Integer>toList());

บันทึก:

ให้ความสนใจกับCollectors.<Integer>toList()วิธีการทั่วไปนี้ช่วยให้คุณหลีกเลี่ยงข้อผิดพลาด "ประเภทไม่ตรงกัน: ไม่สามารถแปลงจากList<Object>เป็นList<Integer>"


4
  1. ใช้ฝรั่ง:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = Lists.newArrayList(sourceArray);
  2. ใช้ Apache Commons Collections:

    Integer[] array = { 1, 2, 3};
    List<Integer> list = new ArrayList<>(6);
    CollectionUtils.addAll(list, array);

3

หากสิ่งนี้ช่วยได้: ฉันมีปัญหาเดียวกันและเพียงเขียนฟังก์ชันทั่วไปที่รับอาร์เรย์และส่งกลับ ArrayList ประเภทเดียวกันที่มีเนื้อหาเดียวกัน:

public static <T> ArrayList<T> ArrayToArrayList(T[] array) {
    ArrayList<T> list = new ArrayList<T>();
    for(T elmt : array) list.add(elmt);
    return list;
}

ถ้ามันไม่ช่วยอะไรล่ะ ถ้าอย่างนั้นคุณทำอะไร ?? ... jk :)
SᴀᴍOnᴇᴌᴀ

2

อาร์เรย์ที่กำหนด:

    int[] givenArray = {2,2,3,3,4,5};

การแปลงอาเรย์จำนวนเต็มเป็นรายการจำนวนเต็ม

วิธีหนึ่ง: boxed () -> ส่งคืน IntStream

    List<Integer> givenIntArray1 = Arrays.stream(givenArray)
                                  .boxed()
                                  .collect(Collectors.toList());

วิธีที่สอง: แมปองค์ประกอบของสตรีมไปยังจำนวนเต็มแล้วรวบรวม

หมายเหตุ: การใช้ mapToObj คุณสามารถแปลงแต่ละอิลิเมนต์ int ให้เป็นสตริงสตรีม, สตรีมถ่าน ฯลฯ โดยใส่ i เป็น (char) i

    List<Integer> givenIntArray2 = Arrays.stream(givenArray)
                                         .mapToObj(i->i)
                                         .collect(Collectors.toList());

การแปลงประเภทอาร์เรย์หนึ่งไปเป็นอีกประเภทหนึ่งตัวอย่าง:

List<Character> givenIntArray2 = Arrays.stream(givenArray)
                                             .mapToObj(i->(char)i)
                                             .collect(Collectors.toList());

1

ดังนั้นมันขึ้นอยู่กับเวอร์ชัน Java ที่คุณพยายาม -

Java 7

 Arrays.asList(1, 2, 3);

หรือ

       final String arr[] = new String[] { "G", "E", "E", "K" };
       final List<String> initialList = new ArrayList<String>() {{
           add("C");
           add("O");
           add("D");
           add("I");
           add("N");
       }};

       // Elements of the array are appended at the end
       Collections.addAll(initialList, arr);

หรือ

Integer[] arr = new Integer[] { 1, 2, 3 };
Arrays.asList(arr);

ใน Java 8

int[] num = new int[] {1, 2, 3};
List<Integer> list = Arrays.stream(num)
                        .boxed().collect(Collectors.<Integer>toList())

ข้อมูลอ้างอิง - http://www.codingeek.com/java/how-to-convert-array-to-list-in-java/


1

คุณช่วยปรับปรุงคำตอบนี้ได้ไหมเพราะนี่คือสิ่งที่ฉันใช้ แต่ฉันไม่ชัดเจน 100% มันใช้งานได้ดี แต่ intelliJ ได้เพิ่ม WeatherStation ใหม่ [0] ทำไมต้องเป็น 0

    public WeatherStation[] removeElementAtIndex(WeatherStation[] array, int index)
    {
        List<WeatherStation> list = new ArrayList<WeatherStation>(Arrays.asList(array));
        list.remove(index);
        return list.toArray(new WeatherStation[0]);
    }


ทำไมเราควรปรับปรุงคำถามของคุณ ไม่ว่าคุณจะรู้คำตอบหรือคุณไม่รู้ แน่นอนคุณควรให้คำตอบที่จริง ๆ ช่วยคนอื่นไม่ใช่คนที่สับสนมากกว่าที่จะช่วย
HimBromBeere

-2

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

  Integer [] arr={1,2};
  Arrays.asList(arr);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.