一个数组(array是保存单一类型的值的固定数量的容器对象。创建数组时将确定数组的长度。创建后,其长度是固定的。您已经在“ Hello World!”应用的main方法中,看到了数组的示例。本节将更详细地讨论数组。
数组 - 图1
10个元素的数组

数组中的每个项目都称为一个元素(**element**,每个元素都可以通过其数字索引(**index**进行访问。如上图所示,编号从0开始。例如,第9个元素将在索引8处访问。
以下程序 ArrayDemo创建一个整型数组,将一些值放入该数组,然后将每个值打印到标准输出。

  1. class ArrayDemo {
  2. public static void main(String[] args) {
  3. // declares an array of integers
  4. int[] anArray;
  5. // allocates memory for 10 integers
  6. anArray = new int[10];
  7. // initialize first element
  8. anArray[0] = 100;
  9. // initialize second element
  10. anArray[1] = 200;
  11. // and so forth
  12. anArray[2] = 300;
  13. anArray[3] = 400;
  14. anArray[4] = 500;
  15. anArray[5] = 600;
  16. anArray[6] = 700;
  17. anArray[7] = 800;
  18. anArray[8] = 900;
  19. anArray[9] = 1000;
  20. System.out.println("Element at index 0: "
  21. + anArray[0]);
  22. System.out.println("Element at index 1: "
  23. + anArray[1]);
  24. System.out.println("Element at index 2: "
  25. + anArray[2]);
  26. System.out.println("Element at index 3: "
  27. + anArray[3]);
  28. System.out.println("Element at index 4: "
  29. + anArray[4]);
  30. System.out.println("Element at index 5: "
  31. + anArray[5]);
  32. System.out.println("Element at index 6: "
  33. + anArray[6]);
  34. System.out.println("Element at index 7: "
  35. + anArray[7]);
  36. System.out.println("Element at index 8: "
  37. + anArray[8]);
  38. System.out.println("Element at index 9: "
  39. + anArray[9]);
  40. }
  41. }

该程序的输出为:

  1. Element at index 0: 100
  2. Element at index 1: 200
  3. Element at index 2: 300
  4. Element at index 3: 400
  5. Element at index 4: 500
  6. Element at index 5: 600
  7. Element at index 6: 700
  8. Element at index 7: 800
  9. Element at index 8: 900
  10. Element at index 9: 1000

在实际编程情况下,您可能会使用受支持的循环结构(looping constructs之一,来遍历数组的每个元素,而不是像前面示例中那样单独编写每行。但是,该示例清楚地说明了数组语法。您将在控制流部分了解各种循环结构(forwhile,和do-while)。

声明变量以引用数组

前面的程序用下面的代码行声明一个数组(名为anArray):

  1. // declares an array of integers
  2. int[] anArray;

像其他类型的变量声明一样,数组声明有两个组成部分:数组的类型和数组的名称。数组的类型写为_type_[],其中_type_包含元素的数据类型;方括号是特殊符号,指示此变量包含一个数组。数组的大小不是其类型的一部分(这就是括号为空的原因)。数组的名称可以是您想要的任何名称,只要它遵循前面在命名部分中讨论的规则和约定即可 。与其他类型的变量一样,声明实际上不会创建数组;它只是告诉编译器该变量将保存指定类型的数组。
同样,您可以声明其他类型的数组:

  1. byte[] anArrayOfBytes;
  2. short[] anArrayOfShorts;
  3. long[] anArrayOfLongs;
  4. float[] anArrayOfFloats;
  5. double[] anArrayOfDoubles;
  6. boolean[] anArrayOfBooleans;
  7. char[] anArrayOfChars;
  8. String[] anArrayOfStrings;

您也可以将方括号放在数组名称的后面:

  1. // this form is discouraged
  2. float anArrayOfFloats[];

但是,惯例不鼓励使用这种形式。方括号标识数组类型,并应与类型名称一起出现。

创建,初始化和访问数组

创建数组的一种方法是使用new运算符。ArrayDemo程序中的下一条语句,为一个数组分配具有10个整型元素的足够内存,并将该数组分配给anArray变量。

  1. // create an array of integers
  2. anArray = new int[10];

如果缺少此语句,则编译器将输出如下错误,并且编译失败:

  1. ArrayDemo.java:4: Variable anArray may not have been initialized.

接下来的几行,将值分配给数组的每个元素:

  1. anArray[0] = 100; // initialize first element
  2. anArray[1] = 200; // initialize second element
  3. anArray[2] = 300; // and so forth

每个数组元素均通过其数字索引进行访问:

  1. System.out.println("Element 1 at index 0: " + anArray[0]);
  2. System.out.println("Element 2 at index 1: " + anArray[1]);
  3. System.out.println("Element 3 at index 2: " + anArray[2]);

另外,您可以使用快捷方式语法创建和初始化数组:

  1. int[] anArray = {
  2. 100, 200, 300,
  3. 400, 500, 600,
  4. 700, 800, 900, 1000
  5. };

在这里,数组的长度由括号之间提供的值的数量确定,并用逗号分隔。
您也可以使用两组或更多组括号,来声明数组的数组(也称为多维数组(multidimensional__ array)),例如String[][] names。因此,必须通过相应数量的索引值来访问每个元素。
在Java编程语言中,多维数组是一个数组,其组件本身就是数组。与C或Fortran中的数组不同的是,它允许行的长度不同,如以下MultiDimArrayDemo程序所示 :

  1. class MultiDimArrayDemo {
  2. public static void main(String[] args) {
  3. String[][] names = {
  4. {"Mr. ", "Mrs. ", "Ms. "},
  5. {"Smith", "Jones"}
  6. };
  7. // Mr. Smith
  8. System.out.println(names[0][0] + names[1][0]);
  9. // Ms. Jones
  10. System.out.println(names[0][2] + names[1][1]);
  11. }
  12. }

该程序的输出为:

  1. Mr. Smith
  2. Ms. Jones

最后,您可以使用内置length属性,来确定任何数组的大小。以下代码将数组的大小打印到标准输出:

  1. System.out.println(anArray.length);


复制数组

System类有一个arraycopy方法,可以使用它,将一个数组的数据有效地复制到另一个数组:

  1. public static void arraycopy(Object src, int srcPos,
  2. Object dest, int destPos, int length)

这两个Object参数指定源数组和目的数组。这三个int参数指定源数组中的起始位置,目的数组中的起始位置和要复制数组元素的数量。
以下程序 ArrayCopyDemo,声明了一个char元素数组,拼写了“decaffeinated”一词。它使用System.arraycopy方法,将数组的子序列复制到第二个数组中:

  1. class ArrayCopyDemo {
  2. public static void main(String[] args) {
  3. char[] copyFrom = { 'd', 'e', 'c', 'a', 'f', 'f', 'e',
  4. 'i', 'n', 'a', 't', 'e', 'd' };
  5. char[] copyTo = new char[7];
  6. System.arraycopy(copyFrom, 2, copyTo, 0, 7);
  7. System.out.println(new String(copyTo));
  8. }
  9. }

该程序的输出为:

  1. caffein

数组操作

数组是编程中使用的强大而又有用的概念。Java SE提供了一些方法,来执行一些与数组有关的最常见操作。例如, ArrayCopyDemo示例使用System类的arraycopy方法,而不是手动遍历源数组的元素,并将每个元素放入目标数组。这是在后台执行的,从而使开发人员可以仅使用一行代码来调用该方法。
为了方便起见,Java SE在java.util.Arrays类中,提供了几种执行数组操作(常见任务,例如复制,排序和搜索数组)的方法 。例如,可以将前面的示例修改为使用java.util.Arrays类的copyOfRange方法,如您在ArrayCopyOfDemo示例中所看到的 。区别在于使用copyOfRange方法,不需要您在调用该方法之前创建目标数组,因为目标数组是由该方法返回的:

  1. class ArrayCopyOfDemo {
  2. public static void main(String[] args) {
  3. char[] copyFrom = {'d', 'e', 'c', 'a', 'f', 'f', 'e',
  4. 'i', 'n', 'a', 't', 'e', 'd'};
  5. char[] copyTo = java.util.Arrays.copyOfRange(copyFrom, 2, 9);
  6. System.out.println(new String(copyTo));
  7. }
  8. }

如您所见,该程序的输出是相同的(caffein),尽管它需要更少的代码行。请注意,copyOfRange方法的第二个参数是要复制的范围的初始索引(包括两个端点),而第三个参数是要复制的范围的最终索引(唯一)。在此示例中,要复制的范围不包括索引9处的数组元素(其中包含字符a)。
java.util.Arrays类中提供的一些其他有用的操作方法是:

  • 在数组中搜索特定值,以获取放置它的索引(binarySearch方法)。
  • 比较两个数组,以确定它们是否相等(equals方法)。
  • 填充数组,以在每个索引处放置一个特定值(fill方法)。
  • 将数组按升序排序,可以使用sort方法按顺序进行此操作,也可以使用Java SE 8中引入的parallelSort方法同时进行。使用多处理器系统对大型数组进行并行排序,要比按顺序进行数组排序要快。