Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
array (数组) 是一个容器对象,它保存固定数量的单种类型的值。数组的长度是在创建数组时建立的。创建后,其长度是固定的。你已经在 "Hello World!" 应用的 main
方法中看到过一个数组的例子。本节更详细地讨论数组。
10 个元素的数组。
数组中的每个项都称为 element (元素),每个元素都通过其数字 index (索引、下标) 访问。如上图所示,编号从 0 开始。例如,第 9 个元素将在索引 8 处访问。
以下程序 ArrayDemo
创建一个整数数组,将一些值放入数组中,并将每个值打印到标准输出。
class ArrayDemo { public static void main(String[] args) { // declares an array of integers int[] anArray; // allocates memory for 10 integers anArray = new int[10]; // initialize first element anArray[0] = 100; // initialize second element anArray[1] = 200; // and so forth 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("Element at index 0: " + anArray[0]); System.out.println("Element at index 1: " + anArray[1]); System.out.println("Element at index 2: " + anArray[2]); System.out.println("Element at index 3: " + anArray[3]); System.out.println("Element at index 4: " + anArray[4]); System.out.println("Element at index 5: " + anArray[5]); System.out.println("Element at index 6: " + anArray[6]); System.out.println("Element at index 7: " + anArray[7]); System.out.println("Element at index 8: " + anArray[8]); System.out.println("Element at index 9: " + anArray[9]); } }
这个程序的输出是:
Element at index 0: 100 Element at index 1: 200 Element at index 2: 300 Element at index 3: 400 Element at index 4: 500 Element at index 5: 600 Element at index 6: 700 Element at index 7: 800 Element at index 8: 900 Element at index 9: 1000
在现实世界的编程情况下,你可能会使用支持的 looping constructs (循环结构) 之一来遍历数组的每个元素,而不是像前面的示例中那样单独编写每行。但是,该示例清楚地说明了数组语法。你将在 Control Flow 部分中了解各种循环结构(for
, while
, and do-while
) 。
上述程序使用以下代码行来声明一个数组(名为 anArray
):
// declares an array of integers int[] anArray;
像其他类型变量的声明一样,数组声明包含两个组件:数组的类型和数组的名称。数组的类型被写为 type[]
,其中 type
是包含元素的数据类型;括号是特殊的符号,表示这个变量包含一个数组。数组的大小不是其类型的一部分(这就是括号为空的原因)。数组的名称可以是任何你想要的,只要它遵循规则和规范,如前面在 naming 部分中所讨论的。与其他类型的变量一样,该声明实际上并不创建数组;它只是告诉编译器该变量将保存指定类型的数组。
同样,你可以声明其他类型的数组:
byte[] anArrayOfBytes; short[] anArrayOfShorts; long[] anArrayOfLongs; float[] anArrayOfFloats; double[] anArrayOfDoubles; boolean[] anArrayOfBooleans; char[] anArrayOfChars; String[] anArrayOfStrings;
你也可以在数组名称后面加上括号:
// this form is discouraged float anArrayOfFloats[];
然而,规范不鼓励这种形式;括号标识数组类型,并应与类型标识一起出现。
创建数组的一种方法是使用 new
运算符。ArrayDemo
程序中的下一个语句为 10 个整型元素分配一个具有足够内存的数组,并将该数组赋值给 anArray
变量。
// create an array of integers anArray = new int[10];
如果缺少这个语句,那么编译器打印出如下所示的错误,编译失败:
ArrayDemo.java:4: Variable anArray may not have been initialized.
接下来的几行为数组的每个元素赋值:
anArray[0] = 100; // initialize first element anArray[1] = 200; // initialize second element anArray[2] = 300; // and so forth
每个数组元素都通过其数字索引进行访问:
System.out.println("Element 1 at index 0: " + anArray[0]); System.out.println("Element 2 at index 1: " + anArray[1]); System.out.println("Element 3 at index 2: " + anArray[2]);
或者,你可以使用快捷语法来创建和初始化一个数组:
int[] anArray = { 100, 200, 300, 400, 500, 600, 700, 800, 900, 1000 };
这里数组的长度由花括号之间提供用逗号分隔的值的数量决定。
你还可以使用两组或更多组括号(如 String[][] names
)声明数组的数组(也称为 multidimensional (多维) 数组)。因此,每个元素必须通过相应数量的索引值进行访问。
在 Java 编程语言中,多维数组是其组件本身就是数组的数组。这与 C 或 Fortran 中的数组不同。这样做的结果是允许行的长度变化,如下面的 MultiDimArrayDemo
程序所示:
class MultiDimArrayDemo { public static void main(String[] args) { String[][] names = { {"Mr. ", "Mrs. ", "Ms. "}, {"Smith", "Jones"} }; // Mr. Smith System.out.println(names[0][0] + names[1][0]); // Ms. Jones System.out.println(names[0][2] + names[1][1]); } }
这个程序的输出是:
Mr. Smith Ms. Jones
最后,你可以使用内置的 length
属性来确定任何数组的大小。以下代码将数组的大小打印到标准输出:
System.out.println(anArray.length);
System
类有一个 arraycopy
方法,你可以使用该方法将数据从一个数组有效地复制到另一个数组中:
public static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length)
两个 Object
参数指定要 from 的数组以及将 to 的数组。三个 int
参数指定源数组中的起始位置,目标数组中的起始位置以及要复制的数组元素的数量。
以下程序 ArrayCopyDemo
声明了一组 char
元素,拼写单词 "decaffeinated"。它使用 System.arraycopy
方法将数组组件的子序列复制到第二个数组中:
class ArrayCopyDemo { public static void main(String[] args) { char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e', 'i', 'n', 'a', 't', 'e', 'd' }; char[] copyTo = new char[7]; System.arraycopy(copyFrom, 2, copyTo, 0, 7); System.out.println(new String(copyTo)); } }
这个程序的输出是:
caffein
数组是编程中使用的一个强大且有用的概念。Java SE 提供了执行与数组相关的一些最常见操作的方法。例如,ArrayCopyDemo
示例使用 System
类的 arraycopy
方法而不是手动迭代元素源数组并将每个放入目标数组中。这是在幕后执行的,使开发人员只需使用一行代码即可调用该方法。
为了你的方便,Java SE 提供了几种在 java.util.Arrays
类中执行数组操作(常见任务,如复制,排序和搜索数组)的方法。例如,前面的示例可以修改为使用 java.util.Arrays
类的 copyOfRange
方法,如你在 ArrayCopyOfDemo
例子中所见。区别在于使用 copyOfRange
方法不需要你在调用方法之前创建目标数组,因为目标数组是由方法返回的:
class ArrayCopyOfDemo { public static void main(String[] args) { char[] copyFrom = {'d', 'e', 'c', 'a', 'f', 'f', 'e', 'i', 'n', 'a', 't', 'e', 'd'}; char[] copyTo = java.util.Arrays.copyOfRange(copyFrom, 2, 9); System.out.println(new String(copyTo)); } }
正如你所看到的,这个程序的输出是相同的(caffein
),尽管它需要更少的代码。请注意,copyOfRange
方法的第二个参数是要复制的范围的初始索引(包含),而第三个参数是要复制的范围的最终索引(不包含)。在此示例中,要复制的范围不包括索引为 9 的数组元素(其中包含字符 a
)。
由 java.util.Arrays
类中的方法提供的一些其他有用的操作有:
binarySearch
方法)。equals
方法)。fill
方法)。sort
方法顺序排序,或使用 Java SE 8 中引入的 parallelSort
方法并行排序。多处理器系统上的大型数组的并行排序比顺序数组排序要快。