การเริ่มต้นของ ArrayList ในหนึ่งบรรทัด


2755

ฉันต้องการสร้างรายการตัวเลือกสำหรับการทดสอบ ตอนแรกฉันทำสิ่งนี้:

ArrayList<String> places = new ArrayList<String>();
places.add("Buenos Aires");
places.add("Córdoba");
places.add("La Plata");

จากนั้นฉันปรับโครงสร้างโค้ดอีกครั้งดังนี้:

ArrayList<String> places = new ArrayList<String>(
    Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

มีวิธีที่ดีกว่าในการทำเช่นนี้?


34
หากสิ่งนี้มีไว้สำหรับการทดสอบหน่วยลองใช้แรงหมุนเพื่อแกว่ง คุณสามารถเขียนรหัสทดสอบของคุณในขณะที่ทดสอบรหัส java และใช้ArrasyList<String> places = ["Buenos Aires", "Córdoba", "La Plata"]
ripper234

3
ใน Java SE 7 คุณสามารถแทนที่ชนิดพารามิเตอร์ของตัวสร้างด้วยชุดพารามิเตอร์ประเภทว่าง (<>): แผนที่ <String, List <String>> myMap = new HashMap <> ();
Rose


2
ใช้ค้ำยันเริ่มต้นคู่ :)
Mohammadreza ทามิ

8
สตรีมของ ("val1", "val2"). รวบรวม (Collector.toList ()); // สร้าง ArrayList, Java8 solution
torina

คำตอบ:


2025

ที่จริงแล้วอาจเป็นวิธีที่ "ดีที่สุด" ในการเริ่มต้นArrayListเป็นวิธีที่คุณเขียนเนื่องจากไม่จำเป็นต้องสร้างใหม่Listในทางใดทางหนึ่ง:

ArrayList<String> list = new ArrayList<String>();
list.add("A");
list.add("B");
list.add("C");

สิ่งที่จับได้คือต้องมีการพิมพ์เล็กน้อยเพื่ออ้างถึงlistอินสแตนซ์นั้น

มีทางเลือกอื่นเช่นการสร้างคลาสภายในแบบไม่ระบุชื่อด้วย initializer อินสแตนซ์ (หรือที่รู้จักในชื่อ "การเริ่มต้นวงเล็บปีกกาคู่"):

ArrayList<String> list = new ArrayList<String>() {{
    add("A");
    add("B");
    add("C");
}};

อย่างไรก็ตามฉันไม่ชอบวิธีการนี้มากนักเพราะสิ่งที่คุณลงท้ายด้วย subclass ArrayListที่มี initializer อินสแตนซ์และคลาสนั้นถูกสร้างขึ้นเพื่อสร้างวัตถุหนึ่งชิ้น - ซึ่งดูเหมือนว่าจะเกินความคิดของฉันเล็กน้อย

สิ่งที่น่ายินดีคือถ้าข้อเสนอ Collection LiteralsสำหรับProject Coinได้รับการยอมรับ (มีกำหนดจะเปิดตัวใน Java 7 แต่ไม่น่าจะเป็นส่วนหนึ่งของ Java 8 เช่นกัน):

List<String> list = ["A", "B", "C"];

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


172
ดูstackoverflow.com/questions/924285สำหรับข้อมูลเพิ่มเติมเกี่ยวกับการกำหนดค่าเริ่มต้น double-brace, pros และ cons
Eddie

6
@Eddie: เรียกลิงก์ได้ดี - ประโยคเดียวในการกำหนดค่าเริ่มต้นสองครั้งนั้นไม่เพียงพอที่จะอธิบายได้อย่างสมบูรณ์
coobird

2
ใช้งานได้เฉพาะเมื่อคุณไม่ได้พึ่งพารายการมวยอัตโนมัติ <Double> list = [1.0, 2.0, 3.0]; ล้มเหลว
Richard B

1
คุณพลาดเซมิโคลอนในการกำหนดค่าเริ่มต้นสองรายการ
Don Larynx

6
เนื่องจากคำตอบนี้เป็นโปรเจกต์ที่มีผู้โหวตสูงสุดและกล่าวถึงฉันคิดว่าคุณควรจะเรียก java ที่ส่งมาพร้อมกับ List.of (... ) ไวยากรณ์: docs.oracle.com/javase/9/docs/api/java/util/ List.html # of-E ...-
Asaf

2155

มันจะง่ายกว่าถ้าคุณเพิ่งประกาศว่าListมันต้องเป็น ArrayList หรือไม่?

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

หรือถ้าคุณมีองค์ประกอบเดียว:

List<String> places = Collections.singletonList("Buenos Aires");

นี่หมายถึงว่าplacesมันไม่เปลี่ยนรูป (พยายามที่จะเปลี่ยนมันจะทำให้เกิดUnsupportedOperationExceptionข้อยกเว้นที่จะโยน)

ในการสร้างรายการที่ไม่แน่นอนซึ่งเป็นรูปธรรมArrayListคุณสามารถสร้างArrayListจากรายการที่ไม่เปลี่ยนรูปได้:

ArrayList<String> places = new ArrayList<>(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

18
@Marcase: คุณไม่สามารถเปลี่ยนคลาสของคุณเพื่อใช้ List แทน ArrayList ได้หรือไม่?
Lawrence Dol

74
เป็นต่อคำตอบของฉันถ้าคุณไม่ได้ใช้วิธีการเฉพาะเพื่อมันจะออกแบบที่ดีกว่าที่จะเปลี่ยนการประกาศไปArrayList Listระบุอินเตอร์เฟสไม่ใช่การนำไปใช้งาน
Christoffer Hammarström

9
@Christoffer Hammarström: หากเขาเปลี่ยนการประกาศเป็นListและใช้รายการ <String> places = Arrays.asList (... ); เขาจะไม่สามารถใช้สถานที่ได้เพิ่ม ("blabla")
maks

57
เพียงเพื่อให้ชัดเจนasList(...)ส่งคืนขนาดคงListที่ที่ระเบิดขึ้นในการดำเนินการกลายพันธุ์เช่นremoveและclearสิ่งที่Listสัญญาเรียกร้องให้การสนับสนุน แม้ว่าคุณจะออกจากการประกาศเป็นListคุณก็ต้องใช้List l = new ArrayList(asList(...))เพื่อที่จะได้รับวัตถุที่ไม่ทิ้งข้อยกเว้น OperationNotSupported หลักการทดแทน Liskov ใคร ๆ
สแปลช

5
@Splash: removeและclearเป็นตัวเลือกการดำเนินการในListดังนั้นจึงเป็นasList(...)ไปตามสัญญา OP ไม่มีที่ไหนบอกว่าเขาต้องการเพิ่มองค์ประกอบเพิ่มเติมในภายหลังตัวอย่างเป็นเพียงของListที่ต้องเริ่มต้นด้วยองค์ประกอบที่สาม
Christoffer Hammarström

872

คำตอบง่ายๆ

ในJava 9หรือใหม่กว่าหลังจากList.of()เพิ่มแล้ว:

List<String> strings = List.of("foo", "bar", "baz");

ด้วยJava 10หรือใหม่กว่าสิ่งนี้สามารถทำให้สั้นลงด้วยvarคำหลัก

var strings = List.of("foo", "bar", "baz");

สิ่งนี้จะทำให้คุณไม่เปลี่ยนรูป Listดังนั้นจึงไม่สามารถเปลี่ยนแปลงได้
ซึ่งเป็นสิ่งที่คุณต้องการในกรณีส่วนใหญ่ที่คุณเตรียมการไว้ล่วงหน้า


Java 8 หรือก่อนหน้า:

List<String> strings = Arrays.asList("foo", "bar", "baz");

สิ่งนี้จะทำให้คุณListได้รับการสนับสนุนจากอาร์เรย์ดังนั้นจึงไม่สามารถเปลี่ยนความยาวได้
แต่คุณสามารถเรียกList.setดังนั้นจึงยังคงไม่แน่นอน


คุณสามารถทำให้Arrays.asListสั้นลงด้วยการนำเข้าแบบคงที่:

List<String> strings = asList("foo", "bar", "baz");

การนำเข้าคงที่:

import static java.util.Arrays.asList;  

IDE ใดที่ทันสมัยจะแนะนำและทำเพื่อคุณโดยอัตโนมัติ
ยกตัวอย่างเช่นใน IntelliJ IDEA คุณกดและเลือกAlt+EnterStatic import method...


อย่างไรก็ตามฉันไม่แนะนำให้ย่อList.ofวิธีการให้สั้นลงofเพราะจะทำให้เกิดความสับสน
List.ofสั้นพอแล้วและอ่านได้ดี


ใช้Streamของ

ทำไมต้องเป็นList?
ด้วย Java 8 หรือใหม่กว่าคุณสามารถใช้อันStreamที่ยืดหยุ่นกว่าได้:

Stream<String> strings = Stream.of("foo", "bar", "baz");

คุณสามารถเชื่อมต่อStreams:

Stream<String> strings = Stream.concat(Stream.of("foo", "bar"),
                                       Stream.of("baz", "qux"));

หรือคุณสามารถเปลี่ยนจาก a Streamเป็นList:

import static java.util.stream.Collectors.toList;

List<String> strings = Stream.of("foo", "bar", "baz").collect(toList());

แต่ควรเพียงแค่ใช้โดยไม่เก็บไปStreamList


หากคุณต้องการจริงๆโดยเฉพาะjava.util.ArrayList

(คุณอาจไม่ทำเช่นนั้น)
ในการพูดJEP 269 (เน้นที่เหมือง):

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


หากคุณต้องการทั้ง prepopulate ArrayList และเพิ่มไปหลังจากนั้น (ทำไม?) การใช้งาน

ArrayList<String> strings = new ArrayList<>(List.of("foo", "bar"));
strings.add("baz");

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

ArrayList<String> strings = new ArrayList<>(asList("foo", "bar"));
strings.add("baz");

หรือใช้Stream:

import static java.util.stream.Collectors.toCollection;

ArrayList<String> strings = Stream.of("foo", "bar")
                             .collect(toCollection(ArrayList::new));
strings.add("baz");

แต่อีกครั้งมันจะดีกว่าที่จะเพียงแค่ใช้โดยตรงแทนการจัดเก็บภาษีไปยังStreamList


โปรแกรมไปยังส่วนต่อประสานไม่ใช่เพื่อการนำไปใช้งาน

คุณบอกว่าคุณได้ประกาศรายชื่อไว้ArrayListในรหัสของคุณแล้ว แต่คุณควรทำอย่างนั้นถ้าคุณใช้สมาชิกบางคนArrayListที่ไม่ได้อยู่ในListนั้น

ซึ่งคุณมักจะไม่ทำ

โดยปกติแล้วคุณก็ควรจะประกาศตัวแปรโดยอินเตอร์เฟซทั่วไปมากที่สุดที่คุณจะใช้ (เช่นIterable, CollectionหรือList) และเริ่มต้นพวกเขาด้วยการดำเนินงานเฉพาะ (เช่นArrayList, LinkedListหรือArrays.asList())

มิฉะนั้นคุณจะ จำกัด รหัสของคุณเฉพาะประเภทนั้นและมันจะยากที่จะเปลี่ยนเมื่อคุณต้องการ

ตัวอย่างเช่นหากคุณส่งผ่านArrayListไปยังvoid method(...):

// Iterable if you just need iteration, for (String s : strings):
void method(Iterable<String> strings) { 
    for (String s : strings) { ... } 
}

// Collection if you also need .size(), .isEmpty(), or .stream():
void method(Collection<String> strings) {
    if (!strings.isEmpty()) { strings.stream()... }
}

// List if you also need .get(index):
void method(List<String> strings) {
    strings.get(...)
}

// Don't declare a specific list implementation
// unless you're sure you need it:
void method(ArrayList<String> strings) {
    ??? // You don't want to limit yourself to just ArrayList
}

อีกตัวอย่างหนึ่งจะเสมอประกาศตัวแปรInputStreamแม้ว่ามันมักจะเป็นFileInputStreamหรือBufferedInputStreamเพราะวันหนึ่งเร็ว ๆ นี้คุณหรือคนอื่นจะต้องการที่จะใช้บางชนิดอื่น ๆ InputStreamของ


3
@ jollyroger: Arrays.asListเป็นวิธีการคงที่ ดูdocs.oracle.com/javase/1.5.0/docs/guide/language/ …
Christoffer Hammarström

2
@ ChristofferHammarströmในกรณีนี้ความคิดของฉันเริ่มต้นบอกฉันว่าการนำเข้าคงที่มีความคล้ายคลึงกับตัวแปรทั่วโลกและภัยที่เกี่ยวข้องกับการใช้งานดังกล่าว สมมติฐานนี้ถูกต้องและเป็นเหตุผลสำหรับคำตอบที่คล้ายกันข้างต้นได้รับคะแนนเสียงมากขึ้น?
jollyroger

2
คำตอบข้างต้นฉันคิดว่าคุณกำลังพูดถึงถูกสร้างขึ้นเมื่อปีก่อน และไม่ปัญหาของตัวแปรทั่วโลกก็คือพวกมันไม่แน่นอน พวกเขาไม่มีอะไรเกี่ยวข้องกับการนำเข้าแบบคงที่
Christoffer Hammarström

2
หากคุณไม่ต้องการนำเข้าแบบคงที่คุณยังสามารถกำหนดเส้นทางแบบเต็มไปยังวิธีการแบบคงที่ asList เช่น: List <String> strings = java.util.Arrays.asList ("", "");
Geert Weening

2
หรือคุณสามารถใช้ import java.util.Arrays และ Arrays.asList ("", ""); คุณไม่จำเป็นต้องใช้การนำเข้าแบบคงที่ คุณไม่จำเป็นต้องใช้เส้นทางแบบเต็ม วิธีการแบบคงที่ไม่สนใจการนำเข้า พวกเขาจะรำคาญถ้าคุณใช้อินสแตนซ์เพื่อค้นหาพวกเขา
candied_orange

111

หากคุณต้องการรายการขนาดง่ายๆ 1:

List<String> strings = new ArrayList<String>(Collections.singletonList("A"));

หากคุณต้องการรายการของวัตถุต่าง ๆ :

List<String> strings = new ArrayList<String>();
Collections.addAll(strings,"A","B","C","D");

57

ด้วยGuavaคุณสามารถเขียน:

ArrayList<String> places = Lists.newArrayList("Buenos Aires", "Córdoba", "La Plata");

ใน Guava ยังมีตัวสร้างสแตติกที่มีประโยชน์อื่น ๆ คุณสามารถอ่านเกี่ยวกับพวกเขาที่นี่


1
ฉันค่อนข้างมั่นใจว่าคุณสามารถทำสิ่งนี้ได้java.util.Arraysเช่นList<String> names = Arrays.asList("Beckah", "Sam", "Michael");
เบคคาห์

2
วิธี @beckah Arrays.asLists สร้างวัตถุประเภทรายการในขณะที่คำถามเกี่ยวกับการสร้าง ArrayList
Paweł Adamski


34

การรวบรวมตัวอักษรไม่ได้ทำให้เป็น Java 8 แต่เป็นไปได้ที่จะใช้ Stream API เพื่อเริ่มต้นรายการในหนึ่งบรรทัดที่ค่อนข้างยาว:

List<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toList());

หากคุณต้องให้แน่ใจว่าคุณListเป็นArrayList:

ArrayList<String> places = Stream.of("Buenos Aires", "Córdoba", "La Plata").collect(Collectors.toCollection(ArrayList::new));

34

กับ และเหนือกว่าตามที่แนะนำในJEP 269: วิธีการอำนวยความสะดวกในโรงงานสำหรับการสะสมสิ่งนี้สามารถทำได้โดยใช้ตัวอักษรสำหรับการสะสมตอนนี้ด้วย -

List<String> list = List.of("A", "B", "C");

Set<String> set = Set.of("A", "B", "C");

วิธีการที่คล้ายกันจะนำไปใช้Mapเช่นกัน -

Map<String, String> map = Map.of("k1", "v1", "k2", "v2", "k3", "v3")

ซึ่งคล้ายกับข้อเสนอ Collection Collectionตามที่ระบุไว้โดย @coobird ชี้แจงเพิ่มเติมใน JEP เช่นกัน -


ทางเลือก

การเปลี่ยนแปลงภาษาได้รับการพิจารณาหลายครั้งและถูกปฏิเสธ:

ข้อเสนอโครงการเหรียญ, 29 มีนาคม 2009

ข้อเสนอโครงการเหรียญ, 30 มีนาคม 2009

การอภิปราย JEP 186 เรื่อง lambda-dev, มกราคม - มีนาคม 2014

ข้อเสนอทางภาษาได้รับการตั้งค่าตามความต้องการของข้อเสนอแบบอิงไลบรารีตามที่สรุปไว้ในข้อความนี้

ที่เกี่ยวข้อง: อะไรคือจุดสำคัญของวิธีการอำนวยความสะดวกสำหรับการรวบรวมใน Java 9


31
import com.google.common.collect.ImmutableList;

....

List<String> places = ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");

4
ฉันไม่ต้องการเพิ่มการพึ่งพาใหม่เพียงเพื่อทำเช่นนั้น
Macarse

6
นั่นเป็นสิ่งเดียวกันCollections.unmodifiableList(Arrays.asList("Buenos Aires", "Córdoba", "La Plata"))ซึ่งกลายเป็นunmodifiableList(asList("Buenos Aires", "Córdoba", "La Plata"))การนำเข้าแบบคงที่ คุณไม่ต้องการ Google Collections สำหรับสิ่งนี้
Christoffer Hammarström

9
ไม่มันไม่เหมือนกัน ในฐานะที่เป็น ImmutableList กำลังบันทึกว่า Immutability ในประเภทผลลัพธ์เมื่อ unmodifiableList ทำการ masquerades เป็นรายการปกติ
David Pierre

2
นอกจากคอลเลกชัน google ยังเสนอรายการอาร์เรย์ที่ไม่แน่นอน: List <String> = Lists.newArrayList ("Buenos Aires", "Córdoba", "La Plata");
L. Holanda

3
คุณจะส่งImmutableListต่อไปยังวิธีอื่น ๆ ที่ใช้Listแล้วจากนั้นคุณก็สูญเสียเอกสารนั้น
Christoffer Hammarström

23

คุณสามารถสร้างวิธีการจากโรงงาน:

public static ArrayList<String> createArrayList(String ... elements) {
  ArrayList<String> list = new ArrayList<String>();
  for (String element : elements) {
    list.add(element);
  }
  return list;
}

....

ArrayList<String> places = createArrayList(
  "São Paulo", "Rio de Janeiro", "Brasília");

แต่มันไม่ได้ดีไปกว่าการปรับโครงสร้างครั้งแรกของคุณ

เพื่อความยืดหยุ่นที่มากขึ้นสามารถเป็นแบบทั่วไปได้:

public static <T> ArrayList<T> createArrayList(T ... elements) {
  ArrayList<T> list = new ArrayList<T>();
  for (T element : elements) {
    list.add(element);
  }
  return list;
}

1
มองย้อนกลับไปที่โพสต์ต้นฉบับมันจะขอเริ่มต้นอาร์เรย์ในหนึ่งบรรทัดไม่ใช่ 7 บรรทัดเพิ่มเติม
L. Holanda

7
@LeoHolanda: การสร้างวิธีการโรงงานสำหรับทุกสิ่งเล็ก ๆ น้อย ๆ ฉันเห็นด้วย แต่ขึ้นอยู่กับสถานการณ์และจำนวนครั้งที่จะใช้วิธีนั้นมันอาจสมเหตุสมผลในการสร้าง การสร้างเลเยอร์สิ่งที่เป็นพิเศษนั้นหมายถึงการกำจัดความซับซ้อนโดยการสร้างวิธีการที่มีความหมายมากขึ้นซึ่งจับภาพเจตนาของนักออกแบบ
Jordão

16

ใน Java 9 เราสามารถเริ่มต้นArrayListในบรรทัดเดียวได้อย่างง่ายดาย:

List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata");

หรือ

List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata"));

วิธีการใหม่ของ Java 9 นี้มีข้อดีมากกว่าวิธีก่อนหน้านี้:

  1. ประสิทธิภาพของอวกาศ
  2. การเปลี่ยนไม่ได้
  3. เธรดที่ปลอดภัย

ดูโพสต์นี้สำหรับรายละเอียดเพิ่มเติม -> ความแตกต่างระหว่าง List.of และ Arrays.asList คืออะไร


8

เกี่ยวกับวิธีที่กะทัดรัดที่สุดในการทำเช่นนี้คือ:

Double array[] = { 1.0, 2.0, 3.0};
List<Double> list = Arrays.asList(array);

8

เพียงใช้รหัสด้านล่างดังต่อไปนี้

List<String> list = new ArrayList<String>() {{
            add("A");
            add("B");
            add("C");
}};

2
@bsd คุณสามารถใช้วิธีนี้เพื่อประกาศรายการก่อนที่จะเข้าวิธีใด ๆ ดังนั้นเมื่อกำหนดตัวแปรคลาสคุณสามารถเพิ่มเนื้อหาลงในรายการโดยไม่ต้องเรียกใช้เมธอด
Melwil

2
การเริ่มต้นวงเล็บปีกกาคู่ควรหลีกเลี่ยงเท่าที่จะทำได้ ดู: stackoverflow.com/a/924326/760393
Raúl

8

ด้วยEclipse Collectionsคุณสามารถเขียนสิ่งต่อไปนี้:

List<String> list = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata");

นอกจากนี้คุณยังสามารถเจาะจงมากขึ้นเกี่ยวกับประเภทและไม่ว่าพวกเขาจะไม่แน่นอนหรือไม่เปลี่ยนรูป

MutableList<String> mList = Lists.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableList<String> iList = Lists.immutable.with("Buenos Aires", "Córdoba", "La Plata");

คุณสามารถทำเช่นเดียวกันกับชุดและกระเป๋า:

Set<String> set = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableSet<String> mSet = Sets.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet<String> iSet = Sets.immutable.with("Buenos Aires", "Córdoba", "La Plata");

Bag<String> bag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
MutableBag<String> mBag = Bags.mutable.with("Buenos Aires", "Córdoba", "La Plata");
ImmutableBag<String> iBag = Bags.immutable.with("Buenos Aires", "Córdoba", "La Plata");

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



7

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

class A{}
class B extends A{}

public List<A> getAList(){
    return Arrays.asList(new B());
}

ผลลัพธ์ข้างต้นมีข้อผิดพลาดในการรวบรวมเพราะList<B>(ซึ่งเป็นสิ่งที่ถูกส่งกลับโดย Arrays.asList) ไม่ใช่คลาสย่อยของList<A>ถึงแม้ว่าคุณสามารถเพิ่มวัตถุประเภท B ไปยังList<A>วัตถุ ในการหลีกเลี่ยงสิ่งนี้คุณต้องทำสิ่งต่อไปนี้:

new ArrayList<A>(Arrays.<A>asList(b1, b2, b3))

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


6

คุณสามารถใช้คำสั่งด้านล่าง:

ตัวอย่างโค้ด:

String [] arr = {"Sharlock", "Homes", "Watson"};

List<String> names = Arrays.asList(arr);

คุณสามารถอินไลน์นิพจน์แรกเพื่อแก้ปัญหาที่มีขนาดกะทัดรัด:letters = Arrays.asList(new String[]{"A", "B", "C"});
Pavel Repin

5

เหมือนทอมพูดว่า :

List<String> places = Arrays.asList("Buenos Aires", "Córdoba", "La Plata");

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

ArrayList<String> myPlaces = new ArrayList(places);

ถึงแม้ว่านั่นอาจทำให้คุณบ่นกับ 'ประสิทธิภาพ'

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

String[] places = {"Buenos Aires", "Córdoba", "La Plata"};

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

ArrayList<String> myPlaces = new ArrayList(Arrays.asList(places));

ตกลง แต่ในอนาคตคุณต้องมีมากกว่าชื่อสถานที่คุณต้องใช้รหัสประเทศด้วย สมมติว่านี่ยังคงเป็นรายการที่กำหนดไว้ล่วงหน้าซึ่งจะไม่เปลี่ยนแปลงระหว่างเวลาทำงานดังนั้นจึงเหมาะสมที่จะใช้enumชุดซึ่งจะต้องรวบรวมใหม่หากรายการที่จำเป็นต้องมีการเปลี่ยนแปลงในอนาคต

enum Places {BUENOS_AIRES, CORDOBA, LA_PLATA}

จะกลายเป็น:

enum Places {
    BUENOS_AIRES("Buenos Aires",123),
    CORDOBA("Córdoba",456),
    LA_PLATA("La Plata",789);

    String name;
    int code;
    Places(String name, int code) {
      this.name=name;
      this.code=code;
    }
}

Enum มีvaluesวิธีสแตติกที่ส่งกลับอาร์เรย์ที่มีค่าทั้งหมดของ enum ตามลำดับที่ประกาศเช่น:

for (Places p:Places.values()) {
    System.out.printf("The place %s has code %d%n",
                  p.name, p.code);
}

ในกรณีนี้ฉันคิดว่าคุณไม่ต้องการ ArrayList ของคุณ

PS Randyaa แสดงให้เห็นถึงวิธีที่ดีอื่นโดยใช้วิธีการแบบคงที่ยูทิลิตี้Collections.addAll


5

Java 9 มีวิธีการต่อไปนี้เพื่อสร้างการเปลี่ยนรูปรายการที่ :

List<String> places = List.of("Buenos Aires", "Córdoba", "La Plata");

ซึ่งสามารถดัดแปลงได้อย่างง่ายดายเพื่อสร้างรายการที่ไม่แน่นอนหากต้องการ:

List<String> places = new ArrayList<>(List.of("Buenos Aires", "Córdoba", "La Plata"));

วิธีการที่คล้ายกันที่มีอยู่สำหรับและSetMap


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


4

ใช่ด้วยความช่วยเหลือของอาร์เรย์คุณสามารถเริ่มต้นรายการอาร์เรย์ในหนึ่งบรรทัด

List<String> strlist= Arrays.asList("aaa", "bbb", "ccc");



2

ใน Java คุณไม่สามารถทำได้

ArrayList<String> places = new ArrayList<String>( Arrays.asList("Buenos Aires", "Córdoba", "La Plata"));

ตามที่ระบุไว้คุณจะต้องทำการเตรียมใช้งานการรั้งสองครั้ง:

List<String> places = new ArrayList<String>() {{ add("x"); add("y"); }};

แต่สิ่งนี้อาจบังคับให้คุณเพิ่มบันทึกย่อ@SuppressWarnings("serial")หรือสร้าง UUID อนุกรมซึ่งน่ารำคาญ ตัวจัดรูปแบบโค้ดส่วนใหญ่จะทำการแกะคำนั้นลงในหลายข้อความสั่ง / บรรทัด

หรือคุณสามารถทำได้

List<String> places = Arrays.asList(new String[] {"x", "y" });

@SuppressWarnings("unchecked")แต่แล้วคุณอาจต้องการที่จะทำ

นอกจากนี้ตาม javadoc คุณควรทำสิ่งนี้:

List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");

แต่ฉันไม่สามารถคอมไพล์ด้วย JDK 1.6 ได้


5
ไม่ถูกต้อง! คุณสามารถทำบรรทัดแรกและนั่นคือคำตอบที่ถูกต้อง btw
Bohemian

1
Collections.singletonList(messageBody)

หากคุณต้องการรายการหนึ่งรายการ !

คอลเล็กชันมาจากแพ็คเกจjava.util


1

วิธีที่ดีที่สุดที่จะทำ:

package main_package;

import java.util.ArrayList;


public class Stackkkk {
    public static void main(String[] args) {
        ArrayList<Object> list = new ArrayList<Object>();
        add(list, "1", "2", "3", "4", "5", "6");
        System.out.println("I added " + list.size() + " element in one line");
    }

    public static void add(ArrayList<Object> list,Object...objects){
        for(Object object:objects)
            list.add(object);
    }
}

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


1
Objectถ้าคุณไปผ่านทุกปัญหาที่คุณเช่นกันอาจจะทำให้มันเป็นวิธีการที่แม่แบบแทนการใช้ธรรมดา
Robert

1

นี่คือรหัสโดยAbacusUtil

// ArrayList
List<String> list = N.asList("Buenos Aires", "Córdoba", "La Plata");
// HashSet
Set<String> set = N.asSet("Buenos Aires", "Córdoba", "La Plata");
// HashMap
Map<String, Integer> map = N.asMap("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3);

// Or for Immutable List/Set/Map
ImmutableList.of("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet.of("Buenos Aires", "Córdoba", "La Plata");
ImmutableSet.of("Buenos Aires", 1, "Córdoba", 2, "La Plata", 3);

// The most efficient way, which is similar with Arrays.asList(...) in JDK. 
// but returns a flexible-size list backed by the specified array.
List<String> set = Array.asList("Buenos Aires", "Córdoba", "La Plata");

ประกาศ: ฉันเป็นผู้พัฒนา AbacusUtil


0

สำหรับฉัน Arrays.asList () เป็นอุปกรณ์ที่ดีและสะดวกที่สุด ฉันชอบที่จะเริ่มต้นด้วยวิธีนี้เสมอ หากคุณเป็นผู้เริ่มต้นใน Java Collections ฉันต้องการให้คุณอ้างอิงการเริ่มต้น ArrayList


ทำไม Arrays.asList () ดีกว่าการสร้าง ArrayList ใหม่ในหนึ่งบรรทัดด้วยadd()เมธอด?
IgorGanapolsky

0

ทำไมไม่ทำฟังก์ชั่นยูทิลิตี้ง่ายๆที่ทำเช่นนี้?

static <A> ArrayList<A> ll(A... a) {
  ArrayList l = new ArrayList(a.length);
  for (A x : a) l.add(x);
  return l;
}

" ll" หมายถึง "รายการตัวอักษร"

ArrayList<String> places = ll("Buenos Aires", "Córdoba", "La Plata");

0

น่าสนใจว่าไม่มีซับในที่มี เมธอดโอเวอร์โหลดอื่น ๆStream::collect

ArrayList<String> places = Stream.of( "Buenos Aires", "Córdoba", "La Plata" ).collect( ArrayList::new, ArrayList::add, ArrayList::addAll );

-1

ที่จริงแล้วเป็นไปได้ที่จะทำในบรรทัดเดียว:

Arrays.asList(new MyClass[] {new MyClass("arg1"), new MyClass("arg2")})

3
ฉันขอเพิ่มสิ่งนี้ให้กับคำถามได้ไหม คำตอบนี้ครอบคลุมอยู่แล้วหลายครั้งโดยคำตอบอื่น ๆ
Mysticial

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