# 数组

> 原文： [https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html](https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html)

_ 数组 _ 是一个容器对象，它包含固定数量的单一类型的值。创建数组时，将建立数组的长度。创建后，其长度是固定的。您已经在“Hello World！”的`main`方法中看到了一个数组示例。应用。本节更详细地讨论了数组。

![Illustration of an array as 10 boxes numbered 0 through 9; an index of 0 indicates the first element in the array](img/1c76b8eadfd68779ef8986ab2bca7e3b.jpg)

10 个元素的数组。



数组中的每个项称为 _ 元素 _，每个元素由其数字 _ 索引 _ 访问。如上图所示，编号从 0 开始。例如，第 9 个元素将在索引 8 处访问。

以下程序 [`ArrayDemo`](examples/ArrayDemo.java) 创建一个整数数组，将一些值放入数组中，并将每个值打印到标准输出。

```
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

```

在实际编程情况下，您可能会使用受支持的 _ 循环结构之一 _ 来迭代数组的每个元素，而不是像前面的示例中那样单独写入每一行。但是，该示例清楚地说明了数组语法。您将了解[控制流程](flow.html)部分中的各种循环结构（`for`，`while`和`do-while`）。

## 声明变量以引用数组

前面的程序使用以下代码行声明一个数组（名为`anArray`）：

```
// declares an array of integers
int[] anArray;

```

与其他类型的变量的声明一样，数组声明有两个组件：数组的类型和数组的名称。数组的类型写为 `_ 类型 _ []` ，其中 `_ 类型 _` 是包含元素的数据类型;括号是特殊符号，表示此变量包含数组。数组的大小不是其类型的一部分（这就是括号为空的原因）。数组的名称可以是您想要的任何名称，前提是它遵循先前在[命名](variables.html#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`。因此，每个元素必须由相应数量的索引值访问。

在 Java 编程语言中，多维数组是一个数组，其组件本身就是数组。这与 C 或 Fortran 中的数组不同。这样做的结果是允许行的长度不同，如下面的 [`MultiDimArrayDemo`](examples/MultiDimArrayDemo.java) 程序所示：

```
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`参数指定要从复制 _ 的数组和将 _ 复制到 _ 的数组。三个`int`参数指定源数组中的起始位置，目标数组中的起始位置以及要复制的数组元素的数量。_

以下程序 [`ArrayCopyDemo`](examples/ArrayCopyDemo.java) 声明了一系列`char`元素，拼写单词“decafffeinated”。它使用`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`](examples/ArrayCopyDemo.java) 示例使用`System`类的`arraycopy`方法，而不是手动迭代源数组的元素并将每个元素放入目标数组。这是在幕后执行的，使开发人员只使用一行代码来调用该方法。

为方便起见，Java SE 提供了几种在 [`java.util.Arrays`](https://docs.oracle.com/javase/8/docs/api/java/util/Arrays.html) 类中执行数组操作（常见任务，如复制，排序和搜索数组）的方法。例如，可以修改前一个示例以使用`java.util.Arrays`类的`copyOfRange`方法，如 [`ArrayCopyOfDemo`](examples/ArrayCopyOfDemo.java) 示例中所示。区别在于使用`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`方法同时完成。多处理器系统上的大型数组的并行排序比顺序数组排序更快。