该Java教程是针对JDK 8编写的。本页面中描述的示例和实践不利用后续版本引入的改进,并且可能使用不再可用的技术。
请参阅Java语言更改了解Java SE 9及后续版本中更新的语言特性的概要。
请参阅JDK发布说明以获取有关所有JDK版本的新功能、增强功能和已删除或已弃用选项的信息。
一个数组是一个容器对象,它可以容纳固定数量的同一类型的值。数组的长度在创建数组时确定,并且创建后其长度是固定的。你已经在"Hello World!"应用程序的main方法中看到了数组的示例。本节将更详细地讨论数组。
一个包含10个元素的数组。
数组中的每个项目称为一个元素,每个元素通过其数字索引进行访问。如前面的示例所示,编号从0开始。例如,第9个元素将在索引8处访问。
下面的程序ArrayDemo创建一个整数数组,将一些值放入数组中,并将每个值打印到标准输出。
class ArrayDemo {
public static void main(String[] args) {
// 声明一个整数数组
int[] anArray;
// 为10个整数分配内存空间
anArray = new int[10];
// 初始化第一个元素
anArray[0] = 100;
// 初始化第二个元素
anArray[1] = 200;
// 以此类推
anArray[2] = 300;
anArray[3] = 400;
anArray[4] = 500;
anArray[5] = 600;
anArray[6] = 700;
anArray[7] = 800;
anArray[8] = 900;
anArray[9] = 1000;
System.out.println("索引为0的元素:"
+ anArray[0]);
System.out.println("索引为1的元素:"
+ anArray[1]);
System.out.println("索引为2的元素:"
+ anArray[2]);
System.out.println("索引为3的元素:"
+ anArray[3]);
System.out.println("索引为4的元素:"
+ anArray[4]);
System.out.println("索引为5的元素:"
+ anArray[5]);
System.out.println("索引为6的元素:"
+ anArray[6]);
System.out.println("索引为7的元素:"
+ anArray[7]);
System.out.println("索引为8的元素:"
+ anArray[8]);
System.out.println("索引为9的元素:"
+ anArray[9]);
}
}
该程序的输出结果为:
索引为0的元素:100 索引为1的元素:200 索引为2的元素:300 索引为3的元素:400 索引为4的元素:500 索引为5的元素:600 索引为6的元素:700 索引为7的元素:800 索引为8的元素:900 索引为9的元素:1000
在实际的编程情况下,你可能会使用其中一个支持的循环结构来遍历数组的每个元素,而不是像前面的例子中那样逐行编写。然而,该例子清楚地说明了数组的语法。你将在控制流部分学习各种循环结构(for、while和do-while)。
前面的程序使用以下代码行声明了一个数组(名为anArray):
// 声明一个整数数组 int[] anArray;
与其他类型的变量声明类似,数组声明有两个组成部分:数组的类型和数组的名称。数组的类型写作type[],其中type是包含元素的数据类型;方括号是特殊符号,表示该变量持有一个数组。数组的大小不是其类型的一部分(这就是为什么方括号为空的原因)。数组的名称可以是任何你想要的,只要它遵循之前在命名部分中讨论的规则和约定即可。与其他类型的变量一样,声明并不实际创建数组;它只是告诉编译器该变量将持有指定类型的数组。
同样,你可以声明其他类型的数组:
byte[] anArrayOfBytes; short[] anArrayOfShorts; long[] anArrayOfLongs; float[] anArrayOfFloats; double[] anArrayOfDoubles; boolean[] anArrayOfBooleans; char[] anArrayOfChars; String[] anArrayOfStrings;
你也可以将方括号放在数组的名称后面:
// 不推荐使用这种形式 float anArrayOfFloats[];
然而,惯例不鼓励使用这种形式;方括号用于标识数组类型,并应与类型标识一起出现。
创建数组的一种方法是使用new操作符。在ArrayDemo程序中的下一条语句中,分配了足够的内存以存储10个整数元素,并将该数组赋给anArray变量。
// 创建一个整数数组 anArray = new int[10];
如果缺少此语句,则编译器会打印以下错误,并且编译失败:
ArrayDemo.java:4: Variable anArray may not have been initialized.
下面几行代码为数组的每个元素赋值:
anArray[0] = 100; // 初始化第一个元素 anArray[1] = 200; // 初始化第二个元素 anArray[2] = 300; // 依此类推
通过其数字索引访问每个数组元素:
System.out.println("索引为0的元素1:" + anArray[0]);
System.out.println("索引为1的元素2:" + anArray[1]);
System.out.println("索引为2的元素3:" + anArray[2]);
或者,您可以使用简化的语法来创建和初始化数组:
int[] anArray = {
100, 200, 300,
400, 500, 600,
700, 800, 900, 1000
};
在这里,数组的长度由花括号之间以逗号分隔的值的数量确定。
您还可以通过使用两个或更多组括号声明数组的数组(也称为多维数组),例如String[][] names。因此,每个元素必须通过相应数量的索引值进行访问。
在Java编程语言中,多维数组是其组件本身就是数组的数组。这与C或Fortran中的数组不同。由此产生的一个结果是,行的长度允许变化,如下面的MultiDimArrayDemo程序所示:
class MultiDimArrayDemo {
public static void main(String[] args) {
String[][] names = {
{"先生", "夫人", "女士"},
{"史密斯", "琼斯"}
};
// 先生史密斯
System.out.println(names[0][0] + names[1][0]);
// 女士琼斯
System.out.println(names[0][2] + names[1][1]);
}
}
该程序的输出结果是:
先生史密斯 女士琼斯
最后,您可以使用内置的length属性来确定任何数组的大小。以下代码将数组的大小打印到标准输出:
System.out.println(anArray.length);
System类具有一个arraycopy方法,您可以使用它来高效地将数据从一个数组复制到另一个数组:
public static void arraycopy(Object src, int srcPos,
Object dest, int destPos, int length)
这两个Object参数指定要从中复制的数组和要复制到的数组。这三个int参数指定源数组中的起始位置、目标数组中的起始位置以及要复制的数组元素数量。
下面的程序ArrayCopyDemo声明了一个String元素的数组。它使用System.arraycopy方法将数组的一部分连续元素复制到第二个数组中:
class ArrayCopyDemo {
public static void main(String[] args) {
String[] copyFrom = {
"Affogato", "Americano", "Cappuccino", "Corretto", "Cortado",
"Doppio", "Espresso", "Frappucino", "Freddo", "Lungo", "Macchiato",
"Marocchino", "Ristretto" };
String[] copyTo = new String[7];
System.arraycopy(copyFrom, 2, copyTo, 0, 7);
for (String coffee : copyTo) {
System.out.print(coffee + " ");
}
}
}
这个程序的输出是:
Cappuccino Corretto Cortado Doppio Espresso Frappucino Freddo
数组是编程中使用的一个强大且有用的概念。Java SE提供了一些常用的与数组相关的操作方法。例如,ArrayCopyDemo示例使用了System类的arraycopy方法,而不是手动遍历源数组的每个元素并将其放入目标数组中。这个操作在幕后执行,使得开发人员只需要一行代码就可以调用该方法。
为了方便起见,Java SE在java.util.Arrays类中提供了几个执行数组操作的方法(例如复制、排序和搜索数组的常见任务)。例如,前面的示例可以修改为使用java.util.Arrays类的copyOfRange方法,如在ArrayCopyOfDemo示例中所示。不同之处在于,使用copyOfRange方法在调用该方法之前不需要创建目标数组,因为目标数组是方法返回的:
class ArrayCopyOfDemo {
public static void main(String[] args) {
String[] copyFrom = {
"Affogato", "Americano", "Cappuccino", "Corretto", "Cortado",
"Doppio", "Espresso", "Frappucino", "Freddo", "Lungo", "Macchiato",
"Marocchino", "Ristretto" };
String[] copyTo = java.util.Arrays.copyOfRange(copyFrom, 2, 9);
for (String coffee : copyTo) {
System.out.print(coffee + " ");
}
}
}
如你所见,这个程序的输出是相同的,尽管代码行数更少。请注意,copyOfRange方法的第二个参数是要复制的范围的起始索引(包括),而第三个参数是要复制的范围的最终索引(不包括)。在这个示例中,要复制的范围不包括索引为9的数组元素(它包含字符串Lungo)。
java.util.Arrays
在数组中搜索特定值以获取其所在位置的索引(binarySearch方法)。
比较两个数组以确定它们是否相等(equals方法)。
填充数组,使每个索引处都放置特定值(fill方法)。
将数组按升序排序。可以使用sort方法顺序排序,也可以使用Java SE 8中引入的parallelSort方法并发排序。在多处理器系统上,并发排序大型数组比顺序排序更快。
创建一个以数组为源的流(stream方法)。例如,以下语句以与之前示例相同的方式打印copyTo数组的内容:
java.util.Arrays.stream(copyTo).map(coffee -> coffee + " ").forEach(System.out::print);
有关流的更多信息,请参见聚合操作。
将数组转换为字符串。 toString方法将数组的每个元素转换为字符串,用逗号分隔,然后用方括号括起来。例如,以下语句将copyTo数组转换为字符串并打印出来:
System.out.println(java.util.Arrays.toString(copyTo));
此语句打印如下内容:
[Cappuccino, Corretto, Cortado, Doppio, Espresso, Frappucino, Freddo]