オブジェクトの配列 Java

⚡ スマートサマリー

オブジェクトの配列 Java オブジェクト参照を固定サイズの連続したスロットに格納することで、単一の変数にクラスの複数のインスタンスを保持させ、インデックスを介して各インスタンスにアクセスし、反復、変更、およびメソッドへの受け渡しを行うことができます。

  • 📦 参照ストレージ: 各スロットは Java オブジェクトの配列は、オブジェクト自体ではなく、オブジェクトへの参照を保持します。これは、 Java.
  • 🧱 2段階の作成: 配列を new ClassName[size] で割り当て、次に各オブジェクトを new ClassName() で割り当ててから、そのオブジェクトのメソッドを呼び出します。
  • ⚠️ NullPointerException: すべてのスロットは初期状態ではnullです。初期化されていないスロットに対してメソッドを呼び出すと、実行時にNullPointerExceptionが発生します。
  • 🔁 反復: 配列の長さを指定したforループ、または拡張forループを使用して、配列内のすべてのオブジェクトを走査します。
  • 固定サイズ: 配列は割り当て後にサイズを増やすことはできません。実行時にオブジェクトの数が変化する場合は、ArrayListを使用してください。
  • 🏗️ コンストラクタ初期化: 作成時にインラインで渡されるコンストラクタは、事後的にセッターを呼び出すよりも、より短く安全なセットアップを実現します。
  • 🚚 メソッドパラメータ: 配列をメソッドに渡すと参照が渡されるため、メソッド内の変更は呼び出し元から見えるようになります。

オブジェクトの配列 Java

オブジェクトの配列とは何ですか Java?

A Java オブジェクトの配列 同じクラスの複数のオブジェクトインスタンスを単一の固定サイズコンテナに格納します。 値を格納するプリミティブ配列とは異なり、 int, doubleまたは boolean 各スロットに直接格納されるオブジェクトの配列 リファレンス各スロットはオブジェクトのメモリ位置を指し、オブジェクト自体は Java ヒープ。

このレイアウトは、あらゆるオブジェクトが 変数 in Java うまく機能します。配列は、複数のオブジェクト参照をまとめてインデックスでアクセスできるようにするものです。オブジェクトの数が事前にわかっていて、プログラムの実行中に変化しない場合に、自然な選択肢となります。

構文

ClassName[] obj = new ClassName[array_length];

右側にはスペースが割り当てられています array_length 参照はすべて初期化され、 null対象物なし ClassName 現時点では、そのようなオブジェクトへの参照を保持できるコンテナのみが存在する。

オブジェクトの配列を作成する方法 Java

オブジェクトの作業用配列を作成するには、常に 2 つの割り当て手順が必要です。最初の手順では参照コンテナを割り当て、2 番目の手順ではコンテナが指す各オブジェクトを割り当てます。ping 2番目のステップは、最も一般的な原因です 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];2 つの参照変数の配列を割り当てます。 Accountしかし、割り当ては行いません Account オブジェクト。両方のスロットに null、そして呼びかける obj[0].setData(...) 上の null 参照がスローする NullPointerException 実行時。

Java オブジェクトの配列参照変数

ステップ5) 4行目と5行目のコメントを解除してください。これらの2行は実際の Account オブジェクトを割り当てて obj[0] (NAIST) と obj[1]配列には実際の参照が格納され、コードは正常に実行されます。

Java オブジェクトの配列が構築されました

出力:

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

上記で示したセッターベースの初期化方法以外にも、オブジェクトの配列をより簡潔に初期化する方法が3つあります。それぞれの方法は冗長性を犠牲にして明瞭さを優先するため、状況に最適な方法を選択してください。

  1. ループの初期化 配列を割り当てた後、各インデックスを走査して新しいオブジェクトを割り当てます。これは、大規模な配列やオブジェクト数が動的に変化する場合によく用いられる標準的なパターンです。
  2. コンストラクタの初期化 — 作成時に値を直接コンストラクタに渡すため、別途セッターを呼び出す必要はありません。
  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 オブジェクトの配列

オブジェクトの配列が作成されたら、3つのパターンでほぼすべてのアクセスニーズに対応できます。コードがインデックスをどの程度制御する必要があるかに応じて、ループスタイルを選択してください。

クラシック傘 for ループ インデックスへのアクセスが可能になり、要素の置換、隣接要素の比較、部分範囲の反復処理などに便利です。

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

強化された for ループ (「foreach」ループは)インデックスを隠蔽し、インデックスが不要な場合に、より自然な読み心地を実現します。

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どのスロットでも nullnull チェックまたは Optional プログラムがクラッシュするのを防ぎ、正常に動作し続けるようにするため。

オブジェクトの配列とオブジェクトのArrayListの違い Java

オブジェクトの単純な配列は高速で予測可能ですが、実行時にオブジェクトの数が変化すると、その固定サイズが制約となります。 Javaさん コレクションフレームワーク は、大阪で ArrayList 動的な代替案として。以下の表は、それぞれの選択肢が適切な場合を示しています。

機能オブジェクトの配列オブジェクトのArrayList
サイズ作成時に修正自動的に拡大縮小します
宣言Account[] a = new Account[5];List<Account> list = new ArrayList<>();
アクセス要素a[i]list.get(i)
Add element作成後はサポートされませんlist.add(obj)
タイプセーフコンパイル時に宣言によって型付けされるコンパイル時にジェネリクスが強制されます
パフォーマンスインデックス付き読み取りがわずかに高速化償却O(1)加算、要素ごとに若干のオーバーヘッドあり
次のような場合に推奨されますサイズは既知で固定されているサイズは不明、または実行時に変更されます。

メモリ使用量を抑え、インデックス付けを予測することが重要な場合、例えばマトリックスレイアウトやパフォーマンスが重要なホットパスでは、配列を使用します。 ArrayList ほとんどの日常的なアプリケーションコードでは、再割り当てなしで追加や削除ができるという利点が、要素ごとのわずかなオーバーヘッドを上回るため、この方法が採用されています。

よくあるご質問

オブジェクトの配列 Java は、同じクラスのインスタンスへの参照を格納する固定サイズのコンテナです。各スロットはヒープ上のオブジェクトを指し、要素には角括弧を使用した0ベースのインデックスでアクセスします。

ClassName[] arr = new ClassName[size] で配列を宣言し、ループ内で new ClassName() を使用するか、インライン配列リテラルを使用して各オブジェクトを作成します。どちらの手順も必須です。最初の手順では参照スロットのみが割り当てられます。

`new ClassName[size]` は配列自体を割り当てるだけなので、各スロットは最初は null です。そのため、そのスロットに対してメソッドを呼び出すと NullPointerException が発生します。これを解決するには、使用する前に各インデックスに `new ClassName()` を割り当ててください。

配列は作成時にサイズが固定されますが、ArrayListは自動的にサイズが増減します。配列はインデックス付き読み取りが若干高速ですが、ArrayListは日常的なアプリケーションコードで便利な追加、削除、ストリームメソッドを提供します。

インデックスが必要な場合は、arr.length を使用した従来の for ループを使用するか、単純な反復処理には拡張 for-each ループを使用してください。フィルタリングや変換を行う場合は、配列を Arrays.stream(arr) でラップし、必要なパイプラインを連結してください。

パラメータを ClassName[] name として宣言し、配列変数を使用してメソッドを呼び出します。 Java 配列参照を値渡しするため、メソッド内の要素フィールドへの変更は呼び出し元から見える。

機械学習によるコード生成ツールは、2段階のメモリ割り当てパターンを認識し、初心者が忘れがちな`new ClassName()`行を補完します。また、対象となるコレクションのサイズが不明な場合はArrayListを提案し、NullPointerExceptionの発生を減らします。

はい。GitHub Copilotは、ドメインモデルを記述したコメントから、配列宣言、コンストラクタループ、反復ブロック、およびArrayList変換を生成します。 Rev使用前に、正しいコンストラクタ引数と安全なnull処理のためのコードが生成されます。