集合-01-数组

有两方面的问题将数组与其他集合类型区分开来:效率和类型。对于 Java 来说,为保存和访问一系列对象
(实际是对象的句柄)数组,最有效的方法莫过于数组。数组实际代表一个简单的线性序列,它使得元素的
访问速度非常快,但我们却要为这种速度付出代价:创建一个数组对象时,它的大小是固定的,而且不可在
那个数组对象的“存在时间”内发生改变。可创建特定大小的一个数组,然后假如用光了存储空间,就再创

建一个新数组,将所有句柄从旧数组移到新数组。这属于“矢量”( Vector)类的行为,

然而,由于为这种大小的灵活性要付出较大的代价,所以我们认为矢量的效率并没有数组高。


数组和第一类对象
无论使用的数组属于什么类型,数组标识符实际都是指向真实对象的一个句柄。那些对象本身是在内存
“堆”里创建的。堆对象既可“隐式”创建(即默认产生),亦可“显式”创建(即明确指定,用一个 new
表达式)。堆对象的一部分(实际是我们能访问的唯一字段或方法)是只读的length(长度)成员,它告诉
我们那个数组对象里最多能容纳多少元素。对于数组对象,“ []”语法是我们能采用的唯一另类访问方法。
下面这个例子展示了对数组进行初始化的不同方式,以及如何将数组句柄分配给不同的数组对象。它也揭示

出对象数组和基本数据类型数组在使用方法上几乎是完全一致的。唯一的差别在于对象数组容纳的是句柄,
而基本数据类型数组容纳的是具体的数值
//: ArraySize.java
// Initialization & re-assignment of arrays
package c08;
class Weeble {} // A small mythical creature
public class ArraySize {
public static void main(String[] args) {
// Arrays of objects:
Weeble[] a; // Null handle
Weeble[] b = new Weeble[5]; // Null handles
Weeble[] c = new Weeble[4];
for(int i = 0; i < c.length; i++)
c[i] = new Weeble();
Weeble[] d = {
new Weeble(), new Weeble(), new Weeble()
};
// Compile error: variable a not initialized:
//!System.out.println("a.length=" + a.length);
System.out.println("b.length = " + b.length);
// The handles inside the array are
// automatically initialized to null:
for(int i = 0; i < b.length; i++)
System.out.println("b[" + i + "]=" + b[i]);
System.out.println("c.length = " + c.length);
System.out.println("d.length = " + d.length);
a = d;
System.out.println("a.length = " + a.length);
// Java 1.1 initialization syntax:
a = new Weeble[] {
new Weeble(), new Weeble()
};
System.out.println("a.length = " + a.length);
// Arrays of primitives:
int[] e; // Null handle
int[] f = new int[5];
int[] g = new int[4];
for(int i = 0; i < g.length; i++)
g[i] = i*i;
int[] h = { 11, 47, 93 };
// Compile error: variable e not initialized:
//!System.out.println("e.length=" + e.length);
System.out.println("f.length = " + f.length);
// The primitives inside the array are
// automatically initialized to zero:
for(int i = 0; i < f.length; i++)
System.out.println("f[" + i + "]=" + f[i]);
System.out.println("g.length = " + g.length);
211
System.out.println("h.length = " + h.length);
e = h;
System.out.println("e.length = " + e.length);
// Java 1.1 initialization syntax:
e = new int[] { 1, 2 };
System.out.println("e.length = " + e.length);
}
} ///:~
Here’s the output from the program:
b.length = 5
b[0]=null
b[1]=null
b[2]=null
b[3]=null
b[4]=null
c.length = 4
d.length = 3
a.length = 3
a.length = 2
f.length = 5
f[0]=0
f[1]=0
f[2]=0
f[3]=0
f[4]=0
g.length = 4
h.length = 3
e.length = 3
e.length = 2
其中,数组 a 只是初始化成一个 null 句柄。此时,编译器会禁止我们对这个句柄作任何实际操作,除非已正
确地初始化了它。数组 b 被初始化成指向由 Weeble 句柄构成的一个数组,但那个数组里实际并未放置任何
Weeble 对象。然而,我们仍然可以查询那个数组的大小,因为 b 指向的是一个合法对象。这也为我们带来了
一个难题:不可知道那个数组里实际包含了多少个元素,因为 length 只告诉我们可将多少元素置入那个数
组。换言之,我们只知道数组对象的大小或容量,不知其实际容纳了多少个元素。尽管如此,由于数组对象
在创建之初会自动初始化成 null,所以可检查它是否为 null,判断一个特定的数组“空位”是否容纳一个对
象。类似地,由基本数据类型构成的数组会自动初始化成零(针对数值类型)、 null(字符类型)或者
false(布尔类型)。
数组 c 显示出我们首先创建一个数组对象,再将 Weeble 对象赋给那个数组的所有“空位”。数组 d 揭示出
“集合初始化”语法,从而创建数组对象(用 new 命令明确进行,类似于数组 c),然后用 Weeble 对象进行
初始化,全部工作在一条语句里完成。
下面这个表达式:
a = d;
向我们展示了如何取得同一个数组对象连接的句柄,然后将其赋给另一个数组对象,就象我们针对对象句柄
的其他任何类型做的那样。现在, a 和 d 都指向内存堆内同样的数组对象。
Java 1.1 加入了一种新的数组初始化语法,可将其想象成“动态集合初始化”。由 d 采用的 Java 1.0 集合
初始化方法则必须在定义 d 的同时进行。但若采用 Java 1.1 的语法,却可以在任何地方创建和初始化一个数
组对象。例如,假设 hide()方法用于取得一个 Weeble 对象数组,那么调用它时传统的方法是:
212
hide(d);
但在 Java 1.1 中,亦可动态创建想作为参数传递的数组,如下所示:
hide(new Weeble[] {new Weeble(), new Weeble() });
这一新式语法使我们在某些场合下写代码更方便了。
上述例子的第二部分揭示出这样一个问题:对于由基本数据类型构成的数组,它们的运作方式与对象数组极
为相似,只是前者直接包容了基本类型的数据值。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值