数组
Java(TM) 提供了一些类用来管理一组数据或一个数据集合,例如,Vector (详见 java.util.Vector )。当然,你也可以设计自己的类。
Java 数组与用户定义的容器对象如 Vector 实例不同,跟其他语言一样,Java 类型系统对数组提供内嵌的,语言级的语法支持。虽然对数组语言级上的支持增加了语言定义的复杂性,但它是合理的(在很多程序员的脑中),因为数组的使用大大丰富了传统的编程
数组是数据元素的线性组合,其每数据元素可以通过下标 (index) 直接访问。第一个元素下标值为 0;最后一个元素下标值为 n - 1。数组有以下形式:
元素个数
元素类型
第 0 个元素
第 1 个元素
...
第 n - 1 个元素
创建一个数组对象的语法是:
数组定义
<变量类型>[] <变量名>;
这中声明定义了一个数组对象--但没有为数组对象分配空间,也没有 为数组分配元素。你也可以不用在[]中指定数组的大小。
为数组分配空间,用 new 操作符:
int[] x = new int[5]; // array of five elements
Java 原始类型的数组 x 具有如下形式:
5
int
0
0
0
0
0
元素为用户定义类型 Dog 的数组定义如下:
Dog[] dog = new Dog[5];
此定义创建了数组对象本身,而没有创建那些元素:
5
Dog
null address
null address
null address
null address
null address
此后,为了初始化数组元素(元素是引用变量),你可以用 new 操作符创建对象:
dog[0] = new Dog();
...
dog[4] = new Dog();
为了创建多维数组,只用创建数组的数组即可,例如:
T[][] t = new T[10][5];
该定义创建了 10 个数组,数组元素为指向元素为 T 引用的数组的引用。注意该定义并没为 T 的实例分配空间。
下面是定义数组与初始化其元素一步完成的快捷形式,初始化的元素是用{ }括起来的分号隔开的数据值:
数组定义和初始化
<数据类型>[] <变量名> = { <表达式>, <表达式>, ... };
下表给出了一些例子:
数组定义和初始化示例
int x = 4;
int[] anArray = {3, x, 9, 2};
String[] seasons = {"winter", "spring", "summer", "fall"};
注意数组大小由初始化的数目决定。
企图存取一个没有定义的数组元素将产生一个运行时异常 ArrayIndexOutOfBoundsException。存取一个定义了的数组元素但尚未将一个对象的引用分配给该元素将产生异常 NullPointerException。
数组的使用将增强用户定义类型 Dog 的多功能性。假定我们增加一个数组变量来存储狗(dog)的日常食谱,代码如下:
class Dog {
String[] dailyDiet = null;
String barkSound = "Woof.";
String name = "none";
String breed = "unknown";
...
dailyDiet 被初始化为 null,意即此处没有合理的默认值,类定义假定一个存取方法将初始化该字段,而其他使用此变量的方法则应该很好地处理 null 值。
下面,我们提供访问方法来设置和读取食谱:
void setDiet(String[] diet) {
dailyDiet = new String[diet.length];
for (int i = 0; i < diet.length; i++)
dailyDiet[i] =diet[i];
}
String[] getDiet() {
return dailyDiet;
}
setDiet() 方法从参数数组 diet 创建了一个数组(实例变量) dailyDiet,其数组元素的数目由参数 diet 的长度变量 length (所有的数组都有 length 变量)决定。该值直接出现在 new 操作符后的 "[]" 中,用于分配所需数目的元素,每一元素都持有 (hold) 一个 String 的引用变量。
在此,我们对数组使用了 for 循环结构,for 循环的语法是:
for (...; ; ...) ...
for 语句中的循环控制区域由三个分号隔开的部分构成。 第一部分 ... 是一个或多个逗号隔开的初始化语句,在第一次循环之前执行依次。第三部分 ... 是一个或多个逗号隔开的表达式,在每一轮循环之后执行。第二部分是循环检验条件。跟 while 语句一样,检验都在每轮循环之前进行。
for 循环控制区域中将下标变量 i 初始化为 0。在每一轮循环之后它的值加一,这样,在语句组区域 (循环体) 中,我们从参数数组中拷贝每一个引用变量数组元素给实例变量数组。
下面的方法说明了 Dog 的类定义中必须好好处理变量 dailyDiet 的 null 值。
void displayDiet() {
if (dailyDiet == null) {
System.out.println("No diet established for " + getName() + ".");
return;
}
else {
System.out.println("The diet established for " + getName() + " is:");
for (int i = 0; i < dailyDiet.length; i++)
System.out.println(dailyDiet[i]);
}
}
下面的程序创建了一个 Dog 实例,为之制定了一份日常食谱,并将食谱输出:
public class DogDiet {
public static void main(String[] args) {
Dog fido = new Dog();
fido.setName("Fido");
String[] diet = {
"2 quarts dry food",
"1 can meat",
"2 buckets fresh water"
};
fido.setDiet(diet);
fido.displayDiet();
}
}
DogDiet 的输出如下:
D:\>java DogDiet
The diet established for Fido is:
2 quarts dry food
1 can meat
2 buckets fresh water