การสร้างอาร์เรย์ของวัตถุใน Java


197

ฉันยังใหม่กับ Java และในเวลานั้นได้สร้างอาร์เรย์ของวัตถุใน Java

ฉันมีคลาส A เช่น -

A[] arr = new A[4];

แต่นี่เป็นเพียงการสร้างพอยน์เตอร์ (อ้างอิง) ไปยังAและไม่ใช่วัตถุ 4 ตัว ถูกต้องหรือไม่ ฉันเห็นว่าเมื่อฉันพยายามเข้าถึงฟังก์ชั่น / ตัวแปรในวัตถุที่สร้างฉันได้รับข้อยกเว้นตัวชี้โมฆะ เพื่อให้สามารถจัดการ / เข้าถึงวัตถุที่ฉันต้องทำ:

A[] arr = new A[4];
for (int i = 0; i < 4; i++) {
    arr[i] = new A();
}

สิ่งนี้ถูกต้องหรือฉันทำสิ่งผิดปกติหรือไม่ ถ้ามันถูกต้องมันแปลกจริงๆ

แก้ไข: ฉันพบสิ่งประหลาดนี้เพราะใน C ++ คุณเพิ่งพูดใหม่A[4]และมันสร้างวัตถุสี่อย่าง


17
ฉันแค่อยากจะบอกว่านี่เป็นคำถามที่มีประโยชน์มาก ขอบคุณที่ถาม
pandorym

คำตอบ:


262

สิ่งนี้ถูกต้อง

A[] a = new A[4];

... สร้างAการอ้างอิง4 ครั้งคล้ายกับการทำสิ่งนี้:

A a1;
A a2;
A a3;
A a4;

ตอนนี้คุณทำไม่ได้a1.someMethod()หากไม่จัดสรรa1แบบนี้:

a1 = new A();

ในทำนองเดียวกันกับอาเรย์ที่คุณต้องทำ:

a[0] = new A();

... ก่อนใช้งาน


10
คำตอบนี้ช่วยให้ฉันสับสนมากขอบคุณสำหรับการมีอยู่ของมัน
pandorym

1
ฉันมีความสับสนเช่นนี้เนื่องจากฉันมาจากพื้นหลัง C ++ ฉันมักจะคิดเสมอว่าเช่นในnewคำหลักของ C ++ Java ก็เรียกตัวสร้างและจัดสรรหน่วยความจำ I ฉันเดาใน Java newเท่านั้นสร้างการอ้างอิงไม่ใช่วัตถุจริงเมื่อเทียบกับ C ++ ขอบคุณสำหรับคำตอบ.
กฤษณะ Oza

1
@Krishna_Oza ไม่มีความแตกต่างจาก C ++ ที่นี่ ครั้งแรกที่newสร้างวัตถุอาร์เรย์ เหล่านี้เป็นวัตถุที่จัดสรรแบบไดนามิก ("ฮีป") ดังนั้น C ++ A **a = new A*[4]; for (int i = 0; i < 4; ++i) { a[i] = new A(); }คล้ายจะเป็นรหัส
Vsevolod Golovanov

1
ฉันได้รับการอ้างอิงใหม่สร้าง แต่ทำไมยังไม่เริ่มต้นตัวสร้างสำหรับองค์ประกอบของแต่ละอาร์เรย์ใน C ++ นี่อาจเป็นเรื่องงี่เง่า แต่ฉันต้องการถามปัญหาใด ๆ ที่เราจะมีหากเราทำเช่นนั้น ?? @MeBigFatGuy
Jasser

2
@ Jasser - ตัวสร้างองค์ประกอบใดที่คุณจะเรียก? จะเกิดอะไรขึ้นถ้าคอนสตรัคเตอร์องค์ประกอบเดียวใช้อาร์กิวเมนต์เป็นจำนวนมาก คุณจะสร้างวัตถุเหล่านั้นได้อย่างไร
MeBigFatGuy

78

สิ่งนี้ถูกต้อง คุณยังสามารถทำสิ่งต่อไปนี้

A[] a = new A[] { new A("args"), new A("other args"), .. };

ไวยากรณ์นี้ยังสามารถใช้เพื่อสร้างและเริ่มต้นอาร์เรย์ได้ทุกที่เช่นในอาร์กิวเมนต์เมธอด:

someMethod( new A[] { new A("args"), new A("other args"), . . } )

35

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

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

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

การเริ่มต้น - อาร์เรย์จะถูกคืนค่าเป็นค่าเริ่มต้นของชนิดข้อมูลเสมอ แต่เราสามารถเริ่มต้นได้เอง

ประกาศอาร์เรย์ใน Java

นี่คือวิธีที่เราประกาศอาร์เรย์หนึ่งมิติใน Java -

int[] array;
int array[];

Oracle ขอแนะนำให้คุณใช้ไวยากรณ์เดิมเพื่อประกาศอาร์เรย์ นี่คือตัวอย่างอื่น ๆ ของการประกาศทางกฎหมาย -

// One Dimensional Arrays
int[] intArray;             // Good
double[] doubleArray;

// One Dimensional Arrays
byte byteArray[];           // Ugly!
long longArray[];

// Two Dimensional Arrays
int[][] int2DArray;         // Good
double[][] double2DArray;

// Two Dimensional Arrays
byte[] byte2DArray[];       // Ugly
long[] long2DArray[];

และนี่คือตัวอย่างของการประกาศที่ผิดกฎหมาย -

int[5] intArray;       // Don't mention size!
double{} doubleArray;  // Square Brackets please!

instantiation

นี่คือวิธีที่เรา“ ยกตัวอย่าง” หรือจัดสรรหน่วยความจำสำหรับอาร์เรย์ -

int[] array = new int[5];

เมื่อ JVM พบnewคำหลักมันเข้าใจว่าจะต้องจัดสรรหน่วยความจำสำหรับบางสิ่งบางอย่าง และโดยการระบุint[5]เราหมายความว่าเราต้องการอาเรย์ของints, ขนาด 5 ดังนั้น JVM สร้างหน่วยความจำและกำหนดการอ้างอิงของหน่วยความจำที่จัดสรรใหม่ให้กับอาเรย์ซึ่งเป็น "อ้างอิง" ของประเภทint[]

การเริ่มต้น

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

ทั้งหมดในอย่างเดียว..! - เราสามารถประกาศยกตัวอย่างและเริ่มต้นอาร์เรย์ของเราได้ในครั้งเดียว นี่คือไวยากรณ์ -

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

ที่นี่เราไม่ได้พูดถึงขนาดเพราะ JVM สามารถเห็นได้ว่าเราให้ 5 ค่า

ดังนั้นจนกว่าเราจะยกตัวอย่างการอ้างอิงยังคงเป็นโมฆะ ฉันหวังว่าคำตอบของฉันจะช่วยคุณ .. ! :)

แหล่งที่มา - อาร์เรย์ใน Java


5

นี่คือตัวอย่างที่ชัดเจนของการสร้างอาร์เรย์ของออบเจ็กต์พนักงาน 10 ชิ้นโดยมี Constructor ที่รับพารามิเตอร์:

public class MainClass
{  
    public static void main(String args[])
    {
        System.out.println("Hello, World!");
        //step1 : first create array of 10 elements that holds object addresses.
        Emp[] employees = new Emp[10];
        //step2 : now create objects in a loop.
        for(int i=0; i<employees.length; i++){
            employees[i] = new Emp(i+1);//this will call constructor.
        }
    }
}

class Emp{
    int eno;
    public Emp(int no){
        eno = no;
        System.out.println("emp constructor called..eno is.."+eno);
    }
}

3

คุณถูก. นอกเหนือจากนั้นถ้าเราต้องการสร้างอาร์เรย์เฉพาะขนาดที่เต็มไปด้วยองค์ประกอบที่จัดทำโดย "โรงงาน" บางส่วนเนื่องจาก Java 8 (ซึ่งแนะนำstream API ) เราสามารถใช้หนึ่งซับนี้:

A[] a = Stream.generate(() -> new A()).limit(4).toArray(A[]::new);
  • Stream.generate(() -> new A())เป็นเหมือนโรงงานสำหรับองค์ประกอบแยกต่างหากที่สร้างขึ้นตามวิธีที่แลมบ์ดาอธิบาย() -> new A()ซึ่งนำไปปฏิบัติSupplier<A>- อธิบายถึงวิธีการสร้างอินสแตนซ์ A ใหม่แต่ละรายการ
  • limit(4)กำหนดจำนวนขององค์ประกอบที่กระแสจะสร้าง
  • toArray(A[]::new)(ยังสามารถเขียนใหม่เป็นtoArray(size -> new A[size])) - มันช่วยให้เราตัดสินใจ / อธิบายประเภทของอาร์เรย์ที่ควรกลับมา

สำหรับบางชนิดดั้งเดิมคุณสามารถใช้DoubleStream, IntStream, LongStreamซึ่งนอกจากให้กำเนิดเช่นrange rangeClosedและอื่น ๆ น้อย


0

ใช่มันถูกต้องใน Java มีหลายขั้นตอนในการสร้างอาร์เรย์ของวัตถุ:

  1. ประกาศแล้วสร้างอินสแตนซ์ (สร้างหน่วยความจำเพื่อเก็บวัตถุ '4'):

    A[ ] arr = new A[4];
  2. การเริ่มต้นวัตถุ (ในกรณีนี้คุณสามารถเริ่มต้น 4 วัตถุของคลาส A)

    arr[0] = new A();
    arr[1] = new A();
    arr[2] = new A();
    arr[3] = new A();

    หรือ

    for( int i=0; i<4; i++ )
      arr[i] = new A();

ตอนนี้คุณสามารถเริ่มเรียกวิธีการที่มีอยู่จากวัตถุที่คุณเพิ่งทำ ฯลฯ

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

  int x = arr[1].getNumber();

หรือ

  arr[1].setNumber(x);

0

สำหรับคลาสทั่วไปจำเป็นต้องสร้างคลาส wrapper ตัวอย่างเช่น:

Set<String>[] sets = new HashSet<>[10]

ผลลัพธ์ใน: "ไม่สามารถสร้างอาร์เรย์ทั่วไป"

ใช้แทน:

        class SetOfS{public Set<String> set = new HashSet<>();}
        SetOfS[] sets = new SetOfS[10];  

บรรทัดนี้หมายความว่าคุณกำลังพยายามสร้างอาเรย์ของเซตโดยที่ Set type เป็น String?
sofs1

0

รูปแบบทั่วไปที่ประกาศอาร์เรย์ใหม่ใน java มีดังนี้:

type arrayName[] = new type[numberOfElements];

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

ให้เริ่มต้นอาร์เรย์เพื่อเก็บเงินเดือนของพนักงานทุกคนใน บริษัท ขนาดเล็ก 5 คน:

int salaries[] = new int[5];

ชนิดของอาร์เรย์ (ในกรณีนี้int) ใช้กับค่าทั้งหมดในอาร์เรย์ คุณไม่สามารถผสมประเภทในหนึ่งอาร์เรย์

ตอนนี้เราได้เริ่มต้นอาร์เรย์เงินเดือนของเราแล้วเราต้องการใส่ค่าลงไป เราสามารถทำได้ทั้งในระหว่างการเริ่มต้นเช่นนี้

int salaries[] = {50000, 75340, 110500, 98270, 39400};

หรือจะทำในภายหลังเช่นนี้

salaries[0] = 50000;
salaries[1] = 75340;
salaries[2] = 110500;
salaries[3] = 98270;
salaries[4] = 39400;

ตัวอย่างเพิ่มเติมของการสร้างอาร์เรย์: ป้อนคำอธิบายรูปภาพที่นี่

ต้องการเรียนรู้เพิ่มเติมเกี่ยวกับอาร์เรย์ตรวจสอบคู่มือ

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