ขนาดเริ่มต้นสำหรับ ArrayList


257

คุณสามารถกำหนดขนาดเริ่มต้นสำหรับ ArrayList ได้โดยทำ

ArrayList<Integer> arr=new ArrayList<Integer>(10);

อย่างไรก็ตามคุณไม่สามารถทำได้

arr.add(5, 10);

เพราะมันทำให้เกิดข้อยกเว้นนอกขอบเขต

การตั้งค่าขนาดเริ่มต้นคืออะไรหากคุณไม่สามารถเข้าถึงพื้นที่ที่คุณจัดสรรได้?

ฟังก์ชั่นการเพิ่มนั้นถูกกำหนดไว้add(int index, Object element)ดังนั้นฉันจึงไม่ได้เพิ่มเข้าไปในดัชนี 10


52
อันที่จริงไม่ชัดเจนจากเอกสารที่รายการจะต้องมีอย่างน้อยnรายการที่เพิ่มก่อนที่คุณจะสามารถset/addรายการn-1
การรับรู้

5
การรับรู้: ฉันไม่รู้ว่ามันชัดเจนหรือไม่ แต่มีการระบุไว้ หนึ่งมีการอ่าน JavaDoc อย่างระมัดระวังแถว: IndexOutOfBoundsException - ถ้าดัชนีอยู่นอกช่วง (ดัชนี <0 | | ดัชนี> = ขนาด ())
Natix

3
อืมผู้สร้างบอกว่า "สร้างรายการที่ว่างเปล่าด้วยความจุเริ่มต้นที่ระบุ" โดยคำนึงถึงรายการที่ว่างเปล่าไม่สามารถมีดัชนีได้ 5 แต่ฉันยอมรับว่านี่อาจไม่ปรากฏให้เห็นในตอนแรก ...
quaylar

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

1
สิ่งที่ numbskull ออกแบบคอลเลกชันด้วยวิธีนี้! กองกำลังนี้ทำงานซ้ำซ้อนสำหรับการสร้างอินสแตนซ์ขนานของโครงสร้างที่มีองค์ประกอบความยาวผันแปร (เช่น ArrayList <String []> โดยที่แต่ละอาร์เรย์สามารถมีความยาวแตกต่างกันได้) หากหน่วยความจำได้รับการจัดสรรแล้วดังนั้นรายการไม่จำเป็นต้องทำการจัดสรรใหม่หลังจากเพิ่มองค์ประกอบ N ดัชนีเหล่านั้นควรสามารถเข้าถึงได้โดยตรงตั้งแต่เริ่มต้น Oracle ไม่มีใครเรียนรู้รูปแบบนี้หลังจาก C / C ++, C #, Objective C และ Swift หรือไม่!
patrickjp93

คำตอบ:


387

คุณกำลังสับสนขนาดของรายการอาเรย์ด้วยความจุ:

  • ขนาดคือจำนวนขององค์ประกอบในรายการ;
  • ความจุเป็นวิธีที่หลาย ๆ องค์ประกอบของรายการที่อาจเกิดขึ้นสามารถรองรับได้โดยไม่ต้องจัดสรรโครงสร้างภายในของมัน

เมื่อคุณโทรnew ArrayList<Integer>(10)คุณกำลังตั้งค่าความจุเริ่มต้นของรายการไม่ใช่ขนาดของมัน กล่าวอีกนัยหนึ่งเมื่อสร้างในลักษณะนี้รายการอาร์เรย์เริ่มชีวิตของมันที่ว่างเปล่า

วิธีหนึ่งในการเพิ่มองค์ประกอบสิบรายการในรายการอาร์เรย์คือโดยใช้การวนซ้ำ:

for (int i = 0; i < 10; i++) {
  arr.add(0);
}

เมื่อทำสิ่งนี้แล้วคุณสามารถแก้ไของค์ประกอบที่ดัชนี 0..9


51
1: ห่วงสั้นคือมันจะมีประโยชน์ที่จะพูดว่าขนาดจะต้องมีอย่างน้อยwhile(arr.size() < 10) arr.add(0); 10เช่นคุณสามารถใช้arr.set(9, n);
Peter Lawrey

10
+1: การตอบสนองที่ยอดเยี่ยมฉันจะให้ +10 ถ้าทำได้ ไม่ชัดเจนในทันทีจาก api ว่าทำไมคุณไม่สามารถตั้งค่าทั้งขนาดเริ่มต้นและความจุเริ่มต้นในการเรียกคอนสตรัคเตอร์เดียวได้ คุณต้องอ่านผ่าน api และพูดว่า "โอ้ฉันเดาว่า ArrayList ไม่มีวิธีหรือตัวสร้างที่จะทำ"
demongolem

@PeterLawrey รหัสของคุณอาจสั้นกว่านี้ แต่มีวิธีการเรียกสองวิธีต่อการวนซ้ำแบบวนซ้ำ
Neuralmer

@ neuralmer ฉันคาดหวัง size () และ add () ให้ inline ดังนั้นจึงไม่มีการเรียกเมธอดจริงเกิดขึ้นที่ runtime
Peter Lawrey

109

หากคุณต้องการรายการที่มีขนาดที่กำหนดไว้ล่วงหน้าคุณยังสามารถใช้:

List<Integer> arr = Arrays.asList(new Integer[10]);

11
ข้อเสียเล็กน้อยที่นี่ผลลัพธ์Listเต็มไปด้วยค่า Null ด้วย Guava เราสามารถทำInts.asList(new int[10])ซึ่งจะเริ่มต้นรายการของเราด้วย0s รูปแบบที่สะอาด แต่ขอบคุณสำหรับตัวอย่าง
dimo414

1
คำถามพูดถึง ArrayList <E> คุณกำลังใช้รายการ <E> ไม่มีใครสังเกตสิ่งนี้ ??? ยิ่งกว่านั้นพวกเขายังได้ตอบคำถามที่ไม่เกี่ยวข้องนี้ด้วย! ฉันไม่ลงคะแนนคำตอบของคุณเพราะฉันไม่เคยทำ เพียงแค่ ... Godssake!
Apostolos

3
@Apostolos ArrayListคือการดำเนินการของListอินเตอร์เฟซและส่งกลับArrays.asList ArrayListฉันขอแนะนำให้คุณค้นหา polymorphism
เลียมพอตเตอร์

ส่งคืนรายการที่มีขนาดคงที่ พยายามที่จะเพิ่มองค์ประกอบอื่น ๆ อีกมากมายUnsupportedOperationException
Koray Tugay

47

ถ้าคุณต้องการใช้ Collections.fill (รายการ, obj); เพื่อเติมรายการด้วยวัตถุที่ทำซ้ำหรือคุณสามารถใช้

ArrayList<Integer> arr=new ArrayList<Integer>(Collections.nCopies(10, 0));

บรรทัดจะคัดลอก 10 ครั้ง 0 ใน ArrayList ของคุณ


20

ความจุของArrayListไม่ได้เป็นเช่นเดียวกับของขนาด ขนาดเท่ากับจำนวนองค์ประกอบที่มีในArrayList(และListการนำไปใช้งานอื่น ๆ)

ความจุเป็นเพียงความยาวของอาร์เรย์พื้นฐานที่ใช้ในการจัดเก็บ internaly องค์ประกอบของที่ArrayListและอยู่เสมอมากกว่าหรือเท่ากับขนาดของรายการ

เมื่อเรียกset(index, element)ใช้รายการความindexสัมพันธ์กับจำนวนจริงขององค์ประกอบรายการ (= ขนาด) (ซึ่งเป็นศูนย์ในรหัสของคุณดังนั้นAIOOBEถูกโยน) ไม่ใช่ความยาวของอาร์เรย์ (= ความจุ) (ซึ่งเป็นรายละเอียดการใช้งานเฉพาะ ไปที่ArrayList)

setวิธีเป็นเรื่องธรรมดาที่ทุกListการใช้งานเช่นการLinkedListซึ่งไม่ได้นำมาใช้จริงโดยอาร์เรย์ แต่เป็นห่วงโซ่การเชื่อมโยงของรายการ

แก้ไข : คุณใช้add(index, element)วิธีการจริงไม่ใช่set(index, element)แต่หลักการเหมือนกันที่นี่


10

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

    String [] test = new String[length];
    test[0] = "add";

5
OP ต้องการใช้รายการในตอนแรก ... ไม่ใช่อาร์เรย์
เตฟาน

9

10 คือความจุเริ่มต้นของ AL ไม่ใช่ขนาด (ซึ่งคือ 0) คุณควรพูดถึงความจุเริ่มต้นที่มีค่าสูงเมื่อคุณจะมีองค์ประกอบมากมายเพราะจะช่วยหลีกเลี่ยงค่าใช้จ่ายในการขยายกำลังการผลิตเมื่อคุณเพิ่มองค์ประกอบ


6

ฉันเดาคำตอบที่แน่นอนสำหรับคำถามของคุณคือ:

การตั้งค่าขนาดเริ่มต้นบน ArrayList จะช่วยลด nr จำนวนครั้งที่การจัดสรรหน่วยความจำภายในจะเกิดขึ้น รายการได้รับการสนับสนุนโดยอาร์เรย์ หากคุณระบุเช่นความจุเริ่มต้น 0 แล้วที่การแทรกครั้งแรกขององค์ประกอบอาร์เรย์ภายในจะต้องมีการปรับขนาด หากคุณมีแนวคิดคร่าวๆว่าจะมีรายการองค์ประกอบกี่รายการของคุณการตั้งค่าความจุเริ่มต้นจะลด nr ของการจัดสรรหน่วยความจำใหม่เกิดขึ้นในขณะที่คุณใช้รายการ



3

การมาสายนี้ แต่หลังจากJava 8ฉันพบวิธีต่อไปนี้ด้วยStreamAPI ที่กระชับยิ่งขึ้นและสามารถเป็นทางเลือกของคำตอบที่ยอมรับได้

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

Arrays.stream(new int[size]).boxed().collect(Collectors.toList())

ที่sizeเป็นที่ต้องการListขนาดและไม่มีข้อเสียที่กล่าวถึงนี่องค์ประกอบทั้งหมดในจะเริ่มต้นเป็นList0

(ฉันทำการค้นหาอย่างรวดเร็วและไม่เห็นstreamคำตอบใด ๆ ที่โพสต์ - โปรดแจ้งให้เราทราบหากคำตอบนี้ซ้ำซ้อนและฉันสามารถลบออกได้)


1

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

เพียงโทร:

arr.add(10)

เพื่อเพิ่มจำนวนเต็มใน ArrayList ของคุณ


1

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


1

หากคุณต้องการเพิ่ม 10 รายการArrayListคุณอาจลอง:

for (int i = 0; i < 10; i++)
    arr.add(i);

หากคุณประกาศตัวแปรขนาดอาร์เรย์แล้วคุณจะใช้ตัวแปรsizeแทนตัวเลข '10'


1

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

  int index = 5;
  int size = 10;

  Integer[] array = new Integer[size];
  array[index] = value;
  ...
  List<Integer> list = Arrays.asList(array);

หรือ

  List<Integer> list = Arrays.asList(new Integer[size]);
  list.set(index, value);

0

ArrayList myList = new ArrayList (10);

//  myList.add(3, "DDD");
//  myList.add(9, "III");
    myList.add(0, "AAA");
    myList.add(1, "BBB");

    for(String item:myList){
        System.out.println("inside list : "+item);
    }

/ * ประกาศ capasity เริ่มต้นของ arraylist ไม่ได้เป็นเพียงการประหยัดเวลาในการเปลี่ยนแปลงภายใน เมื่อเราเพิ่มองค์ประกอบภายในตรวจสอบ capasity เพื่อเพิ่ม capasity คุณสามารถเพิ่มองค์ประกอบที่ 0 ดัชนีเริ่มแรกแล้ว 1 และอื่น ๆ * /


0

Streamสองเซ็นต์ของฉันใน ฉันคิดว่ามันจะดีกว่าที่จะใช้

IntStream.generate(i -> MyClass.contruct())
         .limit(INT_SIZE)
         .collect(Collectors.toList());

ด้วยความยืดหยุ่นในการใส่ค่าเริ่มต้นใด ๆ

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