24.md 9.5 KB
Newer Older
W
init  
wizardforcel 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265
# 数组

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

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

<center>![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 个元素的数组。

</center>

数组中的每个项称为 _ 元素 _,每个元素由其数字 _ 索引 _ 访问。如上图所示,编号从 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`方法同时完成。多处理器系统上的大型数组的并行排序比顺序数组排序更快。