该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]