对象数组 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 在运行时。
步骤5) 取消注释第 4 行和第 5 行。这两行会创建实际的 Account 对象并将它们分配给 obj[0] 和 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
除了上面提到的基于 setter 的初始化方法之外,对象数组还可以用三种更简洁的方式进行初始化。每种方法都以牺牲代码简洁性为代价,因此请选择最适合具体情况的方法。
- 循环初始化 — 先分配数组,然后遍历每个索引并分配一个新的对象。这是大型数组或对象数量动态变化时的标准模式。
- 构造函数初始化 — 在创建时直接将值传递给构造函数,因此不需要单独调用 setter。
- 数组字面量初始化 — 使用内联语句在单个语句中声明和填充。
{ ... }初始化器,非常适合小型固定装置。
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 保持程序运行,避免崩溃。
对象数组与对象 ArrayList 的区别 Java
普通的对象数组速度快、可预测,但一旦运行时对象数量发生变化,其固定大小就会成为一种限制。 Java's Collections 框架提供 ArrayList 作为动态替代方案。下表列出了每种选择的适用情况。
| 特性 | 对象数组 | 对象数组列表 |
|---|---|---|
| 尺寸 | 创建时已固定 | 自动增大和缩小 |
| 声明 | Account[] a = new Account[5]; | List<Account> list = new ArrayList<>(); |
| 访问元素 | a[i] | list.get(i) |
| 添加元素 | 创建后不支持 | list.add(obj) |
| 类型安全 | 编译时类型声明 | 泛型在编译时强制执行 |
| 性能 | 索引读取速度略微加快 | 摊销 O(1) 增加,每个元素有一些开销 |
| 首选 | 尺寸已知且固定 | 大小未知或运行时会发生变化。 |
当内存占用小且索引可预测至关重要时,例如在矩阵布局或对性能要求极高的热路径中,请使用数组。 ArrayList 在大多数日常应用程序代码中,因为无需重新分配即可添加和删除内存的能力超过了每个元素的小开销。



