オブジェクトの配列 Java
⚡ スマートサマリー
オブジェクトの配列 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 実行時。
ステップ5) 4行目と5行目のコメントを解除してください。これらの2行は実際の Account オブジェクトを割り当てて obj[0] (NAIST) と obj[1]配列には実際の参照が格納され、コードは正常に実行されます。
出力:
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つあります。それぞれの方法は冗長性を犠牲にして明瞭さを優先するため、状況に最適な方法を選択してください。
- ループの初期化 配列を割り当てた後、各インデックスを走査して新しいオブジェクトを割り当てます。これは、大規模な配列やオブジェクト数が動的に変化する場合によく用いられる標準的なパターンです。
- コンストラクタの初期化 — 作成時に値を直接コンストラクタに渡すため、別途セッターを呼び出す必要はありません。
- 配列リテラルの初期化 — インラインを使用して単一のステートメントで宣言およびデータ投入
{ ... }初期化子。小規模な固定セットに最適です。
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 ほとんどの日常的なアプリケーションコードでは、再割り当てなしで追加や削除ができるという利点が、要素ごとのわずかなオーバーヘッドを上回るため、この方法が採用されています。



