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. 拜访数组
如何拜访数组元素呢?咱们能够通过元素的地位来实现。
如上面这段代码将在管制台上打印数字 10anArray[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 库还有一些实用的办法能够操作数组。