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

⚡ สรุปอย่างชาญฉลาด

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

  • 📦 พื้นที่จัดเก็บข้อมูลอ้างอิง: แต่ละช่องใน Java อาร์เรย์ของอ็อบเจ็กต์จะเก็บการอ้างอิงไปยังอ็อบเจ็กต์ ไม่ใช่ตัวอ็อบเจ็กต์เอง คล้ายกับตัวแปรอ็อบเจ็กต์ทั่วไป Java.
  • 🧱 การสร้างแบบสองขั้นตอน: จัดสรรอาร์เรย์ด้วยชื่อคลาสใหม่[ขนาด] จากนั้นจัดสรรแต่ละอ็อบเจ็กต์ด้วยชื่อคลาสใหม่() ก่อนที่จะเรียกใช้เมธอดบนอ็อบเจ็กต์นั้น
  • ⚠️ NullPointerException: ทุกช่องเริ่มต้นด้วยค่าว่าง (null) การเรียกเมธอดบนช่องที่ยังไม่ได้กำหนดค่าเริ่มต้นจะทำให้เกิด NullPointerException ในระหว่างการทำงาน
  • 🔁 การวนซ้ำ: ใช้ลูป for ที่กำหนดความยาวของอาร์เรย์ หรือใช้ลูป for แบบพิเศษเพื่อวนลูปผ่านทุกอ็อบเจ็กต์ในอาร์เรย์
  • 📏 ขนาดคงที่: อาร์เรย์ไม่สามารถขยายขนาดได้หลังจากจัดสรรแล้ว ควรใช้ ArrayList เมื่อจำนวนอ็อบเจ็กต์เปลี่ยนแปลงในระหว่างการทำงาน
  • 🏗️ การเริ่มต้นคอนสตรัคเตอร์: การส่งค่าคอนสตรัคเตอร์แบบอินไลน์ระหว่างการสร้าง จะทำให้การตั้งค่าสั้นลงและปลอดภัยกว่าการเรียกใช้เมธอด setter ภายหลัง
  • 🚚 พารามิเตอร์ของเมธอด: การส่งอาร์เรย์ไปยังเมธอดจะส่งผ่านการอ้างอิง ดังนั้นการเปลี่ยนแปลงภายในเมธอดจะปรากฏให้ผู้เรียกใช้เห็น

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

อาร์เรย์ของอ็อบเจ็กต์คืออะไรใน Java?

A Java อาร์เรย์ของวัตถุ อาร์เรย์แบบออบเจ็กต์จะเก็บอินสแตนซ์ของออบเจ็กต์คลาสเดียวกันหลายๆ ตัวไว้ในคอนเทนเนอร์ขนาดคงที่เพียงตัวเดียว ซึ่งแตกต่างจากอาร์เรย์แบบดั้งเดิมที่เก็บค่าต่างๆ เช่น int, doubleหรือ boolean ในแต่ละช่องจะมีอาร์เรย์ของวัตถุจัดเก็บอยู่ การอ้างอิงแต่ละช่องจะชี้ไปยังตำแหน่งหน่วยความจำของวัตถุ และตัววัตถุเองนั้นก็อยู่ในช่องนั้น Java กอง.

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

วากยสัมพันธ์

ClassName[] obj = new ClassName[array_length];

ด้านขวาจัดสรรพื้นที่สำหรับ array_length การอ้างอิงทั้งหมดได้รับการเริ่มต้นเป็น nullไม่มีวัตถุประสงค์ของ ClassName ยังไม่มีอยู่จริง มีเพียงภาชนะที่สามารถเก็บการอ้างอิงถึงวัตถุเหล่านั้นได้เท่านั้น

วิธีการสร้างอาร์เรย์ของอ็อบเจ็กต์ใน Java

การสร้างอาร์เรย์ของอ็อบเจ็กต์ที่ใช้งานได้นั้นต้องใช้ขั้นตอนการจัดสรรสองขั้นตอนเสมอ ขั้นตอนแรกคือการจัดสรรคอนเทนเนอร์อ้างอิง และขั้นตอนที่สองคือการจัดสรรอ็อบเจ็กต์แต่ละตัวที่คอนเทนเนอร์จะชี้ไป ข้ามไปping ขั้นตอนที่สองเป็นแหล่งที่มาที่พบได้บ่อยที่สุดเพียงแหล่งเดียว NullPointerException สำหรับผู้เริ่มต้น Java รหัส.

ขั้นตอน 1) เปิดของคุณ แก้ไขโค้ด และคัดลอกโค้ดต่อไปนี้:

class ObjectArray {
    public static void main(String args[]) {
        Account obj[] = new Account[2];
        // obj[0] = new Account();
        // obj[1] = new Account();
        obj[0].setData(1, 2);
        obj[1].setData(3, 4);
        System.out.println("For Array Element 0");
        obj[0].showData();
        System.out.println("For Array Element 1");
        obj[1].showData();
    }
}

class Account {
    int a;
    int b;

    public void setData(int c, int d) {
        a = c;
        b = d;
    }

    public void showData() {
        System.out.println("Value of a = " + a);
        System.out.println("Value of b = " + b);
    }
}

ขั้นตอน 2) บันทึกไฟล์เป็น ObjectArray.javaจากนั้นคอมไพล์และรันโปรแกรม

ขั้นตอน 3) โปรดสังเกตข้อผิดพลาด ลองแก้ไขข้อผิดพลาดก่อนดำเนินการต่อในขั้นตอนที่ 4

ขั้นตอน 4) ตรวจสอบสาย Account obj[] = new Account[2];ฟังก์ชันนี้จะจัดสรรอาร์เรย์ของตัวแปรอ้างอิงสองตัวที่มีชนิดข้อมูลเป็น Accountแต่ไม่ได้จัดสรรใดๆ Account วัตถุ ทั้งสองช่องสามารถบรรจุได้ nullและการโทร obj[0].setData(...) เมื่อ null การอ้างอิงโยน NullPointerException ที่รันไทม์

Java อาร์เรย์ของอ็อบเจ็กต์อ้างอิงตัวแปร

ขั้นตอน 5) ลบเครื่องหมายคอมเมนต์ออกจากบรรทัดที่ 4 และ 5 บรรทัดทั้งสองนี้สร้างค่าจริง Account วัตถุและกำหนดให้กับวัตถุเหล่านั้น obj[0] และ obj[1]ตอนนี้อาร์เรย์เก็บค่าอ้างอิงจริงแล้ว และโค้ดทำงานได้อย่างราบรื่น

Java อาร์เรย์ของวัตถุที่ถูกเติมข้อมูล

Output:

For Array Element 0
Value of a = 1
Value of b = 2
For Array Element 1
Value of a = 3
Value of b = 4

วิธีการกำหนดค่าเริ่มต้นให้กับอาร์เรย์ของอ็อบเจ็กต์ในภาษาโปรแกรม Java

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

  1. การเริ่มต้นลูป — จัดสรรอาร์เรย์ จากนั้นวนไปตามดัชนีแต่ละตัวและกำหนดอ็อบเจ็กต์ใหม่เข้าไป นี่เป็นรูปแบบมาตรฐานสำหรับอาร์เรย์ขนาดใหญ่หรือเมื่อจำนวนอ็อบเจ็กต์เปลี่ยนแปลงได้
  2. การเริ่มต้นคอนสตรัคเตอร์ — ส่งค่าโดยตรงไปยังคอนสตรัคเตอร์ในขณะสร้าง จึงไม่จำเป็นต้องเรียกใช้เมธอด setter แยกต่างหาก
  3. การเริ่มต้นค่าคงที่ของอาร์เรย์ — ประกาศและกำหนดค่าในคำสั่งเดียวด้วยคำสั่งแบบอินไลน์ { ... } ตัวเริ่มต้น เหมาะสำหรับชุดคงที่ขนาดเล็ก
class Account {
    int a, b;

    public Account(int a, int b) {   // constructor
        this.a = a;
        this.b = b;
    }
}

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

        // 1) Loop initialisation
        Account[] loopArr = new Account[3];
        for (int i = 0; i < loopArr.length; i++) {
            loopArr[i] = new Account(i, i * 10);
        }

        // 2) Constructor initialisation, one slot at a time
        Account[] ctorArr = new Account[2];
        ctorArr[0] = new Account(1, 2);
        ctorArr[1] = new Account(3, 4);

        // 3) Array literal initialisation
        Account[] litArr = {
            new Account(5, 6),
            new Account(7, 8),
            new Account(9, 10)
        };

        System.out.println("loop size   = " + loopArr.length);
        System.out.println("ctor size   = " + ctorArr.length);
        System.out.println("literal size= " + litArr.length);
    }
}

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

การวนซ้ำและการเข้าถึงองค์ประกอบใน Java อาร์เรย์ของวัตถุ

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

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

for (int i = 0; i < obj.length; i++) {
    System.out.println("Element " + i);
    obj[i].showData();
}

ที่เพิ่มขึ้น for ห่วง (ลูป “for-each”) จะซ่อนดัชนีและทำให้การอ่านเป็นธรรมชาติมากขึ้นเมื่อไม่จำเป็นต้องใช้ดัชนี:

for (Account acc : obj) {
    acc.showData();
}

สตรีม (Java (อายุ 8 ปีขึ้นไป) แปลงอาร์เรย์ให้เป็นไปป์ไลน์ ซึ่งมีประโยชน์สำหรับการกรองและการแมปpingหรือการรวมข้อมูลโดยไม่ต้องเขียนลูป:

import java.util.Arrays;

Arrays.stream(obj)
      .filter(acc -> acc.a > 0)
      .forEach(Account::showData);

ในการอ่านหรืออัปเดตข้อมูลขององค์ประกอบเดียว ให้ใช้การเข้าถึงดัชนีโดยตรง ตัวอย่างเช่น obj[1].setData(10, 20)ตรวจสอบความยาวก่อนเสมอ obj.length หลีกเลี่ยง ArrayIndexOutOfBoundsExceptionเมื่อใดก็ตามที่ช่องใดช่องหนึ่งสามารถเป็นได้ nullป้องกันการเข้าถึงด้วยการตรวจสอบค่าว่างหรือ Optional เพื่อให้โปรแกรมทำงานต่อไปได้โดยไม่ล่ม

อาร์เรย์ของอ็อบเจ็กต์ กับ อาร์เรย์ลิสต์ของอ็อบเจ็กต์ Java

การใช้แถวของอ็อบเจ็กต์แบบธรรมดาจะรวดเร็วและคาดเดาได้ แต่ขนาดที่ตายตัวของมันจะกลายเป็นข้อจำกัดทันทีที่จำนวนอ็อบเจ็กต์เปลี่ยนแปลงในระหว่างการทำงาน Javaกรอบงานคอลเลกชันของ 's ให้บริการ ArrayList ในฐานะทางเลือกแบบไดนามิก ตารางด้านล่างแสดงให้เห็นว่าแต่ละตัวเลือกเหมาะสมกับสถานการณ์ใดบ้าง

คุณสมบัติ (Feature)อาร์เรย์ของวัตถุอาร์เรย์ลิสต์ของอ็อบเจ็กต์
ขนาดแก้ไขแล้วตั้งแต่การสร้างขยายและหดตัวโดยอัตโนมัติ
การประกาศAccount[] a = new Account[5];List<Account> list = new ArrayList<>();
องค์ประกอบการเข้าถึงa[i]list.get(i)
เพิ่มองค์ประกอบไม่ได้รับการสนับสนุนหลังจากสร้างแล้วlist.add(obj)
ประเภทความปลอดภัยกำหนดประเภทข้อมูลในขั้นตอนการคอมไพล์โดยการประกาศบังคับใช้ Generics ในระหว่างการคอมไพล์
ประสิทธิภาพการอ่านดัชนีที่เร็วกว่าเล็กน้อยเพิ่ม O(1) แบบเฉลี่ย มีค่าใช้จ่ายเพิ่มเติมต่อองค์ประกอบบางส่วน
นิยมใช้เมื่อขนาดเป็นที่ทราบและคงที่ขนาดไม่แน่นอนหรือเปลี่ยนแปลงขณะทำงาน

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

คำถามที่พบบ่อย

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

ประกาศอาร์เรย์ด้วย ClassName[] arr = new ClassName[size] จากนั้นสร้างแต่ละอ็อบเจ็กต์ด้วย new ClassName() ในลูปหรือด้วยอาร์เรย์ลิเทอรัลแบบอินไลน์ ทั้งสองขั้นตอนจำเป็นต้องทำ โดยขั้นตอนแรกจะจัดสรรช่องอ้างอิงเท่านั้น

เนื่องจากเมธอด `new ClassName[size]` จะจัดสรรเฉพาะอาร์เรย์นั้นเองเท่านั้น ทุกช่องเริ่มต้นด้วยค่าว่าง ดังนั้นการเรียกเมธอดใดๆ บนช่องนั้นจะทำให้เกิด NullPointerException วิธีแก้ไขคือการกำหนดค่า `new ClassName()` ให้กับแต่ละดัชนีก่อนใช้งาน

อาร์เรย์มีขนาดคงที่ซึ่งเลือกไว้ตอนสร้าง ในขณะที่ ArrayList จะขยายและหดตัวโดยอัตโนมัติ อาร์เรย์ให้ความเร็วในการอ่านดัชนีที่เร็วกว่าเล็กน้อย และ ArrayList เพิ่มเมธอด add, remove และ stream ที่สะดวกสำหรับโค้ดแอปพลิเคชันทั่วไป

ใช้ลูป for แบบคลาสสิกกับ arr.length เมื่อต้องการดัชนี หรือใช้ลูป for-each ที่ปรับปรุงแล้วสำหรับการวนซ้ำแบบง่ายๆ สำหรับการกรองหรือการแปลง ให้ห่ออาร์เรย์ด้วย Arrays.stream(arr) และเชื่อมต่อไปป์ไลน์ที่คุณต้องการ

ประกาศพารามิเตอร์เป็น ClassName[] name จากนั้นเรียกเมธอดโดยใช้ตัวแปรอาร์เรย์ Java เมธอดนี้ส่งผ่านการอ้างอิงอาร์เรย์ด้วยค่า ดังนั้นการเปลี่ยนแปลงฟิลด์ขององค์ประกอบภายในเมธอดจะปรากฏให้ผู้เรียกใช้เห็น

ตัวสร้างโค้ดการเรียนรู้ของเครื่องสามารถจดจำรูปแบบการจัดสรรแบบสองขั้นตอนและเติมเต็มบรรทัด `new ClassName()` ที่ขาดหายไปซึ่งผู้เริ่มต้นมักลืม นอกจากนี้ยังแนะนำ `ArrayList` เมื่อไม่ทราบขนาดของคอลเลกชันเป้าหมาย ซึ่งช่วยลดข้อผิดพลาด `NullPointerException`

ใช่แล้ว GitHub Copilot สร้างการประกาศอาร์เรย์ ลูปในคอนสตรัคเตอร์ บล็อกการวนซ้ำ และการแปลงเป็น ArrayList จากความคิดเห็นที่อธิบายโมเดลโดเมน Revตรวจสอบโค้ดที่สร้างขึ้นเพื่อตรวจสอบความถูกต้องของพารามิเตอร์ในคอนสตรัคเตอร์และการจัดการค่า null อย่างปลอดภัยก่อนใช้งาน

สรุปโพสต์นี้ด้วย: