สร้างอาร์เรย์ของ Arraylists


175

ฉันต้องการสร้างอาร์เรย์ของรายการอาร์เรย์ดังนี้:

ArrayList<Individual>[] group = new ArrayList<Individual>()[4]

แต่มันไม่ได้รวบรวม ฉันจะทำสิ่งนี้ได้อย่างไร


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

13
@SeanPatrickFloyd คุณช่วยอธิบายได้ไหมว่าทำไมอาร์เรย์ถึงเป็นฝันร้ายในการใช้งาน?
ผู้ใช้

3
@ crucifiedsoul แน่นอน อาร์เรย์ไม่สามารถเจริญเติบโตคุณไม่สามารถใส่อะไรเข้าไปในอาร์เรย์อาร์เรย์ไม่แทนที่วิธีการมาตรฐานเช่นเท่ากับแฮชโค้ดหรือ toString ฯลฯ
ฌอนแพทริคฟลอยด์

9
@ SeanPatrickFloyd โอเค - ฉันต้องการอาร์เรย์ทั้งหมดสี่รายการ - ฉันวางแผนที่จะเข้าถึงแต่ละรายการโดยใช้ดัชนี - ฉันไม่ต้องการอาร์เรย์ด้านนอกเพื่อขยายหรือหด - ฉันไม่ต้องการ toString หรือ hashcode ฯลฯ - - สำหรับฉันแล้วอาร์เรย์เป็นตัวเลือกที่ชัดเจนที่นี่คุณจะแนะนำอะไรเป็นทางเลือกในสถานการณ์นี้
BrainSlugs83

4
ตกลงนี่เป็นคำถามเก่า แต่ฉันจะถามต่อไปและดูว่าใครตอบ ฉันเห็นทุกคนพูดถึงว่าทำไมรายการต่างๆจึงเป็นความคิดที่แย่มากการฝึกฝนการเขียนโค้ดที่ไม่ดี ฯลฯ ฉันค้นหาสิ่งนี้เพราะฉันเรียนรู้ที่จะทำแฮ็คโซ่และคำจำกัดความของเชนแฮชคือรายการ! ดังนั้นโครงสร้างข้อมูลการเขียนโปรแกรมกลางสามารถเป็นวิธีการเข้ารหัสที่น่ากลัวได้อย่างไร? หรือสิ่งนี้เพิ่งตกอยู่ในหมวดหมู่ IYKWYD ที่เอ่ยถึง @Sean
jimboweb

คำตอบ:


142

ตามเอกสารของ Oracle :

"คุณไม่สามารถสร้างอาร์เรย์ของพารามิเตอร์ชนิด"

คุณสามารถทำได้:

ArrayList<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>(4);

ตามที่แนะนำโดย Tom Hawting - tackline จะดียิ่งกว่า:

List<List<Individual>> group = new ArrayList<List<Individual>>(4);

20
List<List<Individual>> group = new ArrayList<List<Individual>>();น่าจะดีกว่า
Tom Hawtin - tackline

4
"ไม่สามารถสร้างอาร์เรย์ประเภททั่วไป" หมายถึงอะไร มันไม่สมเหตุสมผลเลยสำหรับฉันเพราะมันไม่ธรรมดาถ้าคุณให้สิ่งที่มันควรจะถือใช่ไหม?
Andy

5
ฉันประหลาดใจใน upvotes เนื่องจากไม่ตอบคำถาม (เช่นฉันต้องการทำสิ่งนี้ฉันจะทำอย่างไร) อาจจะยกเว้นสำหรับประโยคที่ 1
Florian F

15
เหตุใดการอ้างอิงรายการจึงดีกว่า ArrayList
shifu

3
@shifu การอ้างอิงรายชื่อทั่วไปกว่า ArrayList; การประกาศเป็น List แบบนามธรรมจะตัด API ของ ArrayList ที่เกินกว่า List API นั่นเป็นสิ่งที่ดีเพราะจะทำให้การอ้างอิงไปยังรายการนั้นมีความเป็นไปได้ที่ API อาจมีความครบถ้วนสมบูรณ์ของสิ่งที่รายการนั้นต้องการสำหรับทุกเรื่องโดยไม่เกะกะ API ของการอ้างอิงนั้นด้วย ArrayList พิเศษ คุณควรประกาศเป็น ArrayList ก็ต่อเมื่อคุณต้องการบางสิ่งที่เฉพาะเจาะจงจาก API เพื่อให้สามารถใช้งานได้ผ่านการอ้างอิง
cellepo

98

อย่างที่คนอื่น ๆ พูดถึงมันอาจจะดีกว่าถ้าใช้รายการอื่นเพื่อเก็บ ArrayList ไว้ แต่ถ้าคุณต้องใช้อาเรย์:

ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];

4
ดูเหมือนจะไม่มีใครอธิบายได้ว่าทำไมและฉันชอบข้อมูลโค้ดของคุณด้านบน ทำไมคุณแนะนำให้ใช้รายการเหนือสิ่งนี้
clankill3r

3
ถ้ากลุ่มอาร์เรย์ไม่เปลี่ยนแปลงวิธีนี้จะดีกว่าเนื่องจากอาร์เรย์เร็วกว่ารายการ <> คลาส
Borzh

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

3
มีเหตุผลใดที่จะได้รับความนิยมมากกว่า @kelvincer Answer ( ArrayList<String>[] group = new ArrayList[4]) นักแสดงที่ดีคนพิเศษทำอะไรได้บ้าง?
cellepo

2
คุณควรใช้new ArrayList<?>[N]เพื่อหลีกเลี่ยงการใช้ประเภทดิบ
Radiodef

80

งานนี้:

ArrayList<String>[] group = new ArrayList[4];

1
สิ่งนี้น่าพึงพอใจมีประโยชน์ที่ต้องการซึ่งเพิ่ม ArrayList ของวัตถุใด ๆ นอกเหนือจากสตริง (เช่น: ArrayList<String>แทนArrayList<NotString>) เพื่อgroupไม่คอมไพล์
cellepo

12
สิ่งนี้สร้างคำเตือน:Note: hello.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
คณิตศาสตร์

24

คุณสามารถสร้างคลาสที่ขยาย ArrayList ได้

class IndividualList extends ArrayList<Individual> {

}

แล้วสร้างอาร์เรย์

IndividualList[] group = new IndividualList[10];

17

ฉันไม่เข้าใจเลยว่าทำไมทุกคนถึงแนะนำประเภท Genric ให้กับอาร์เรย์โดยเฉพาะสำหรับคำถามนี้

จะทำอย่างไรถ้าความต้องการของฉันคือการจัดทำดัชนีรายการnarray ต่างๆ

ด้วยการประกาศว่าList<List<Integer>>ฉันต้องสร้างn ArrayList<Integer>วัตถุด้วยตนเองหรือใส่วนรอบเพื่อสร้างnรายการหรือวิธีอื่น ๆ ไม่ว่าในทางใดมันจะเป็นหน้าที่ของฉันในการสร้างnรายการ

List<Integer>[] = (List<Integer>[]) new List<?>[somenumber]มันจะไม่ดีถ้าเราประกาศว่าผ่านการหล่อเป็น ฉันเห็นว่ามันเป็นการออกแบบที่ดีโดยที่ไม่ต้องสร้างวัตถุการทำดัชนีทั้งหมด (arraylist) ด้วยตัวเอง

ทุกคนสามารถให้ความกระจ่างแก่ฉันได้ไหมว่าทำไม (รูปแบบนี้) จะเป็นการออกแบบที่ไม่ดีและข้อเสียของมันคืออะไร?


AFAICT ดูเหมือนว่าจะเป็นแนวคิดเกี่ยวกับลัทธิขนส่งสินค้าที่เกิดจากระบบการพิมพ์ที่น่ากลัวที่ Java นำมาสู่ตาราง
BrainSlugs83

@smsIce: มันไม่ใช่การออกแบบที่ไม่ดี ปัญหาคือว่านักเขียนหลายคนไม่ได้อ่านคำถามเต็มหรือเข้าใจอย่างชัดเจน
testo

16

คุณสามารถสร้าง Array of ArrayList

List<Integer>[] outer = new List[number];
for (int i = 0; i < number; i++) {
    outer[i] = new ArrayList<>();
}

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

ในJava 8ขึ้นไปคุณสามารถทำได้ด้วยวิธีที่ดีกว่ามาก

List<Integer>[] outer = new List[number];
Arrays.setAll(outer, element -> new ArrayList<>());

ดียิ่งขึ้นโดยใช้การอ้างอิงวิธีการ

List<Integer>[] outer = new List[10];
Arrays.setAll(outer,  ArrayList :: new);

2
เมื่อคุณใช้ArrayList::newมันจะเรียกตัวArrayList(int)สร้างที่มีดัชนีปัจจุบันเป็นอาร์กิวเมนต์ - ArrayList (1), ArrayList (2), ArrayList (3) เป็นต้นดังนั้นคุณจะจบลงด้วยอาร์เรย์ที่มีขนาดเล็กกว่าหรือใหญ่กว่า ขึ้นอยู่กับการใช้งานของคุณ ฉันจะกีดกันการใช้มันและแทนที่จะชอบวิธีที่สองที่คุณเรียกนวกรรมิกของตัวเองในการแสดงออกแลมบ์ดาของคุณ
Genhis

8

งานนี้อาร์เรย์ของ ArrayList ให้มันลองเพื่อทำความเข้าใจวิธีการทำงาน

import java.util.*;

public class ArrayOfArrayList {
    public static void main(String[] args) {

        // Put the length of the array you need
        ArrayList<String>[] group = new ArrayList[15];
        for (int x = 0; x < group.length; x++) {
            group[x] = new ArrayList<>();
        }

        //Add some thing to first array
        group[0].add("Some");
        group[0].add("Code");

        //Add some thing to Secondarray
        group[1].add("In here");

        //Try to output 'em
        System.out.println(group[0]);
        System.out.println(group[1]);
    }
}

ให้เครดิตแก่ Kelvincer สำหรับรหัสบางส่วน


6

ปัญหาเกี่ยวกับสถานการณ์นี้คือการใช้ arraylist คุณจะได้รับเวลาที่ซับซ้อนของ o (n) สำหรับการเพิ่มที่ตำแหน่งเฉพาะ ถ้าคุณใช้อาร์เรย์คุณสร้างตำแหน่งหน่วยความจำโดยการประกาศอาร์เรย์ของคุณดังนั้นมันจึงเป็นค่าคงที่


การเพิ่มที่ตำแหน่งเฉพาะคือ O (n) สำหรับทั้งอาร์เรย์และ ArrayList การเติมเป็น O (n) สำหรับทั้งอาร์เรย์และ ArrayList
Navin

2
การเพิ่มที่ตำแหน่งเฉพาะคือ O (1) สำหรับอาร์เรย์ มันเป็น O (n) สำหรับ ArrayList แต่ O (1) สำหรับอาร์เรย์
aviemet

3

คุณไม่สามารถสร้างอาร์เรย์ประเภททั่วไปได้ สร้างรายชื่อ ArrayLists:

 List<ArrayList<Individual>> group = new ArrayList<ArrayList<Individual>>();

หรือถ้าคุณต้องการอาร์เรย์จริงๆ (คำเตือน: การออกแบบที่ไม่ดี!):

 ArrayList[] group = new ArrayList[4];

2
  1. การสร้างและการเริ่มต้น

    Object[] yourArray = new Object[ARRAY_LENGTH];
  2. เข้าถึงการเขียน

    yourArray[i]= someArrayList;

    เพื่อเข้าถึงองค์ประกอบของ ArrayList ภายใน:

    ((ArrayList<YourType>) yourArray[i]).add(elementOfYourType); //or other method
  3. การเข้าถึงเพื่ออ่าน

    การอ่านองค์ประกอบอาร์เรย์ฉันเป็นแบบหล่อใช้ ArrayList:

    someElement= (ArrayList<YourType>) yourArray[i];

    สำหรับองค์ประกอบอาร์เรย์ i: เพื่ออ่านองค์ประกอบ ArrayList ที่ดัชนี j

    arrayListElement= ((ArrayList<YourType>) yourArray[i]).get(j);

2

List [] listArr = new ArrayList [4];

บรรทัดด้านบนให้คำเตือน แต่ใช้งานได้ (เช่นสร้าง Array of ArrayList)


1

ในการประกาศอาร์เรย์ของ ArrayLists แบบคงที่เพื่อให้พูดวางตำแหน่งเป็นคะแนน:

ArrayList<Point>[] positionList = new ArrayList[2];

public Main(---) {
    positionList[0] = new ArrayList<Point>(); // Important, or you will get a NullPointerException at runtime
    positionList[1] = new ArrayList<Point>();
}

แบบไดนามิก:

ArrayList<Point>[] positionList;
int numberOfLists;

public Main(---) {
    numberOfLists = 2;
    positionList = new ArrayList[numberOfLists];
    for(int i = 0; i < numberOfLists; i++) {
        positionList[i] = new ArrayList<Point>();
    }
}

แม้จะมีข้อควรระวังและคำแนะนำที่ซับซ้อนบางอย่างที่นี่ แต่ฉันได้พบ ArrayLists หลายชุดเพื่อเป็นโซลูชันที่หรูหราในการเป็นตัวแทนของ ArrayLists ที่เกี่ยวข้องในประเภทเดียวกัน



1

คุณสามารถสร้างเช่นนี้ ArrayList<Individual>[] group = (ArrayList<Individual>[])new ArrayList[4];

คุณต้องสร้างอาเรย์ประเภทที่ไม่ใช่ประเภททั่วไปแล้วจึงแปลงเป็นประเภททั่วไป



0

ฉันคิดว่ามันใช้ง่ายกว่านี้ ...

static ArrayList<Individual> group[];
......
void initializeGroup(int size)
{
 group=new ArrayList[size];
 for(int i=0;i<size;i++)
 {
  group[i]=new ArrayList<Individual>();
 }

0

คุณสามารถทำได้:

// สร้างอาเรย์ประเภท ArrayList

`ArrayList<Integer>[] a = new ArrayList[n];`

// สำหรับแต่ละองค์ประกอบในอาร์เรย์ให้สร้าง ArrayList

for(int i=0; i<n; i++){ 
    a[i] = new ArrayList<Integer>();
}


-1

คุณสามารถสร้างรายการ [] และเริ่มต้นพวกเขาโดยสำหรับวง มันรวบรวมโดยไม่มีข้อผิดพลาด:

List<e>[] l;
for(int i = 0; i < l.length; i++){
    l[i] = new ArrayList<e>();
}

มันทำงานร่วมกับ arrayList [] l เช่นกัน


2
l.lengthไม่ได้กำหนดใน for-loop นี่อาจเป็นข้อผิดพลาดรันไทม์
bourbaki4481472

l ไม่ได้ถูกเตรียมข้อมูลเบื้องต้นให้มีความยาวมันยังคงเป็นตัวชี้โมฆะเมื่อถึงลูป ie List <e> [] l = รายการใหม่ [LENGTH];
Erik
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.