写点什么

Java 中数组参考指南

作者:okokabcd
  • 2022 年 6 月 27 日
  • 本文字数:3414 字

    阅读完需:约 11 分钟

Java中数组参考指南

1. 介绍

本文,我们深入探讨 Java 中一核心概念 - 数组。首先了解什么是数组,然后了解如何使用它们。总的来说,我们将介绍如何:


  • 数组入门

  • 读写数组元素

  • 遍历数组

  • 将数组转化为其对象,如 List 或 Streams

  • 数组的排序、搜索和合并

2. 什么是数组

首先,我们需要定义什么是数组?根据 Java 文档,数组是包含固定数量相同类型的对象。数组中的每个元素都是有序号的,这意味着我们可以使用索引来访问它们。我们可以将数组看作是编号的单元格,每个单元格可以看作是保存一个值的亦是。在 Java 中,编号是从 0 开始的。变量的类型可以是基础类型数组和对象类型数组。这意味着我们可以使用 int, float, boolean, ......同样也可以使用 String, Object 和自定义类型来定义数组。

3. 设置数组

现在我们已经知道数组的定义了,我们深入了解它们的用法。我们将涵盖很多关于如何使用数组的主题。我们将学习一些基础知识,如如何声明和初始化数组,还有更高级的主题如排序和搜索数组。先让我们学习声明和初始化数组。

3.1. 声明

我们从声明开始,在 Java 中有两种声明数组的方法


// 方法一:int[] anArray;
// 方法二:int anOtherArray[];
复制代码


前者比后者应用更广泛。

3.2. 初始化

现在让我们看一下如何初始化数组。同样有多种方法可以初始化一个数组。让我们从一个简单的方法开始:


int[] anArray = new int[10];
复制代码


通过上面的语句,我们初始化了一个包含 10 个 int 元素的数组。注意我们必须指定数组的大小。使用此方法时,我们将每个元素的初始化的默认值为 0,如果元素为 Object,则默认值为 null。另一种方法,我们可以在创建数组时直接为数组设置值:


int[] anArray = new int[]{1, 2, 3, 4, 5};
复制代码


在这里我们初始化了一个包含数字 1 到 5 的五元素数组。使用此方法时,我们不需要指定数组的长度,需要在大括号之间指定数组元素。

4. 访问数组

如何访问数组元素呢?我们可以通过元素的位置来实现。如下面这段代码将在控制台上打印数字 10


anArray[0] = 10;System.out.println(anArray[0]);
复制代码


注意我们是用索引来访问数组元素的,括号内的数字是我们要访问的数组的具体位置。访问单元格时,如果索引为负数或超出最后一个单元格 Java 将抛出 ArrayIndexOutOfBoundException。我们应该注意不要使用负数为索引,或大于或小于数组长度的值为索引。

5. 遍历数组

虽然逐个访问数组很有用,我们也需要经常遍历数组。第一种方法是使用 for 循环:


int[] anArray = new int[]{1, 2, 3, 4, 5};for (int i = 0; i < anArray.length; i++) {    System.out.println(anArray[i]);}
复制代码


上面这段代码将数字 1-5 打印到控制台上,我们利用了数组长度这一属性。我们还可以使用 while 和 do while,以及 for each 来遍历数组。下面使用 foreach 循环:


int[] anArray = new int[]{1, 2, 3, 4, 5};for (int element : anArray) {    System.out.println(element);}
复制代码


这个例子和上一个例子是等价的,但是没有用到索引。在以下情况可以使用 foreach 循环:


  • 不需要修改数组

  • 不需要索引来做其他事情

6. 可变参数

我们已经介绍了创建和操作数组的的基础知识。现在我们将探讨更高级的主题,先从可变参数开始。可变参数用于将任意数量的参数传递给方法:


void varargsMethod(String... varargs) {}
复制代码


这个方法可以传入 0 到任意数量的 String 参数。我们知道在方法内部,会将可变参数转化为一个数组。同样我们也可以将一个数组直接作为可变参数:


String[] anArray = new String[]{"Milk", "Tomato", "Chips"};varargsMethod(anArray);
// 和下面调用方法等效varargsMethod("Milk", "Tomato", "Chips");
复制代码

7. 将数组转化成 List

有时处理 List 会更方便,这里介绍如何将数组转换为列表。一个简单的笨方法来实现:


List<Integer> aList = new ArrayList<>();for (int element : anArray) {    aList.add(element);}
复制代码


另外一种更简洁的方式:


Integer[] anArray = new Integer[]{1, 2, 3, 4, 5};List<Integer> aList = Arrays.asList(anArray);
复制代码


静态方法 Arrays.asList 接受一个可变参数并使用值传递方式创建一个列表,这个方法有一些缺点:


  • 不能使用基础类型数组

  • 我们不能从创建的列表中添加或删除元素,因为它会抛出 UnsupportedOperationException

8. 将数组转化成 Stream

我们现在可以将数组转换为列表,从 Java8 开始提供了 Stream API,我们也有可能需要将数组转换为 Stream。Java 为我们提供了 Arrays.stream 方法:


String[] anArray = new String[]{"Milk", "Tomato", "Chips"};Stream<String> aStream = Arrays.stream(anArray);
复制代码


将一个 Object 数组作为参数传递给该方法,它返回匹配类型的 Stream。当传递一个基础类型数组时它将返回基础数据流。也可以在数组的子集上创建流:


Stream<String> anotherStream = Arrays.stream(anArray, 1, 3);
复制代码


这将创建一个只有"Tomato"和"Chips"字符吕的 Stream<String>。

9. 数组排序

现在我们来对数组进行排序,即按特定顺序重新排列其元素。Arrays 类为我们提供了 sort 方法。有点像流的方法,该方法有很多重载。方法说明:


  • 基础类型数组:按升序排列

  • 对象数组(对象必须实现 Comparable 接口):按照自然顺序排序(依赖于 Comparable 的 compareTo 方法)

  • 泛型数组:根据给定的比较器排序,可以对数组的特定部分进行排序(需要将开始和结束索引传递给方法)


sort 方法背后的算法分别是原始数组和其他数组的快速排序和合并排序。让我们通过一些例子来看看 sort 是如何使用的:


int[] anArray = new int[]{5, 2, 1, 4, 8};Arrays.sort(anArray);// anArray is now {1, 2, 4, 5, 8}
Integer[] anotherArray = new Integer[]{5, 2, 1 4, 8};Arrays.sort(anotherArray);// anotherArray is now {1, 2, 4, 5, 8}
String[] yetAnotherArray = new String[]{"A", "E", "Z", "B", "C"};Arrays.sort(yetAnotherArray, 1, 3, Comparator.comparing(String::toString).reversed());// yetAnotherArray is now {"A", "Z", "E", "B", "C"}
复制代码

10. 搜索数组

搜索数组很简单,可以遍历数组并在数组元素中搜索我们的元素:


int[] anArray = new int[]{5, 2, 1, 4, 8};for (int i = 0; i < anArray.length; i++) {    if (anArray[i] == 4) {        System.out.println("Found at index " + i);        break;    }}
复制代码


上面的代码,我们搜索了数字 4,并在索引 3 处找到了它。如果我们有一个排序数组,我们可以使用另一种解决这群:二分查找。Java 为我们提供了 Arrays.binarySearch 方法。我们必须给它一个数组和一个要搜索的元素。在泛型数组的情况下,我们还必须首先为其提供用于对数组进行排序的比较器, 我们也可以在数组的子集上调用该方法。下面是用二分搜索方法的一个例子:


int[] anArray = new int[]{1, 2, 3, 4, 5};int index = Arrays.binarySearch(anArray, 4);System.out.println("Found at index " + index);
复制代码


注意:前提是一个已经排序的数组。

11. 合并数组

最后让我们看一下如何连接两个数组。一个思路就是创建一个数组,长度为两个数组的和。之后我们再分别添加两个数组的元素。


int[] anArray = new int[]{5, 2, 1, 4, 8};int[] anotherArray = new int[]{10, 4, 9, 11, 2};
int[] resultArray = new int[anArray.length + anotherArray.length];for (int i = 0; i < resultArray.length; i++) { resultArray[i] = (i < anArray.length ? anArray[i] : anOtherArray[i - anArray.length]);}
复制代码


上面的代码,当索引小于第一个数组长度时添加第一个数组元素添加,然后中再添加第二个数组元素。我们也可以使用 Arrays.setAll 方法来避免写循环:


int[] anArray = new int[]{5, 2, 1, 4, 8};int[] anotherArray = new int[]{10, 4, 9, 11, 2};
int[] resultArray = new int[anArray.length + anotherArray.length];Arrays.setAll(resultArray, i -> (i < anArray.length ? anArray[i] : anOtherArray[i - anArray.length]))
复制代码


此方法将根据给定函数设置所有数组元素。此函数将索引与结果相关联。合并数组的第三个方法,System.arraycopy。


System.arraycopy(anArray, 0, resultArray, 0, anArray.length);System.arraycopy(anotherArray, 0, resultArray, anArray.length    , anotherArray.length);
复制代码


调用两次方法,分别将两个数组元素值 copy 到结果数组中。

12. 总结

本文中,我们介绍了 Java 中数组的基本和一些高级用法。我们看到 Java 提供了很多通过 Arrays 来处理数组的方法。Apache Commons 和 Guava 库还有一些实用的方法可以操作数组。

发布于: 刚刚阅读数: 3
用户头像

okokabcd

关注

还未添加个人签名 2019.11.15 加入

一年当十年用的Java程序员

评论

发布
暂无评论
Java中数组参考指南_Java’_okokabcd_InfoQ写作社区