Java 提供了一个数据结构:数组,用于存储相同类型的元素的一个固定大小的连续集合。数组是用于存储数据的集合,但往往将数组认为是相同类型的变量的集合
数组是一种效率最高的存储和随机访问对象引用序列的方式,在性能要求较高的场景中优先考虑数组
一维数组
声明数组变量
首先必须声明数组变量,才能在程序中使用数组1
2
3
4dateType[] arrayRefVar;
eg.
double[] myList;
创建、处理数组
数量变量的声明和创建数组1
2
3
4
5
6
7
8dataType[] arrayRefVar = new dataType[arraySize];
or
dataType[] arrayRefVar = {value0, value1, ..., valuek};
//求数组的大小,数组是定长的,一旦初始化声明后是不可改变长度的
arrayRefVar.length
eg.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
26public class Number {
public static void main(String[] args) {
double[] myList = {7.2, 8.3, 2.0, 3.0};
// 打印所有数组元素
for (int i = 0; i < myList.length; i++) {
System.out.println(myList[i]);
}
// 计算所有元素的总和
double total = 0;
for (int i = 0; i < myList.length; i++) {
total += myList[i];
}
System.out.println(total);
// 查找最大元素
double max = myList[0];
for (int i = 1; i < myList.length; i++) {
if (myList[i] > max) max = myList[i];
}
System.out.println(max);
}
}
变长数组
虽然数组是定长的,一旦初始化声明后是不可改变长度,但是我们可以利用 List 集合 add 方法里面的扩容思路来模拟实现
思路:创建一个长度与原数组不同的新数组,让原数组变量指向新数组,实现长度可变
ArrayList:动态数组,Array 的复杂版本
创建新数组,让原数组变量指向新数组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.day032602;
import java.util.Arrays;
public class Number {
public static void main(String[] args) {
int[] src1 = new int[0];
int[] src2 = new int[3];
src1 = src2;
src1[0] = 1;
src1[1] = 2;
src1[2] = 3;
System.out.println(Arrays.toString(src1));//把数组转化成字符串输出
}
}
//输出结果
[1,2,3]使用 ArrayList 代替数组,通过泛型 ArrayList 可以储存不同类型的对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18package com.day032602;
import java.util.Arrays;
import java.util.ArrayList;
public class Number {
public static void main(String[] args) {
ArrayList<Integer> a = new ArrayList<>();
a.add(1);
a.add(2);
a.add(3);
//输出数组元素数量
System.out.println(a.size());
}
}
//输出结果
3
for-each 循环
for-each 循环或者加强型循环,它能在不使用下标的情况下遍历数组1
2
3
4
5//语法格式
for(type element: array)
{
System.out.println(element);
}
eg.1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18public class Number {
public static void main(String[] args) {
double[] myList = {7.2, 8.3, 2.0, 3.0};
//打印所有数组元素
for (double element: myList){
System.out.println(element);
}
}
}
//输出结果
7.2
8.3
2.0
3.0
数组的查找
查找是在数组中寻找特定元素的过程
两种常用的方法:线性查找(linear searching)和二分查找(binary searching)
线性查找法
线性查找法将要查找的关键字 key 与数组中的元素逐个进行比较。如果匹配成功,线性查找法则返回与关键字匹配的元素在数组中的下标;如果没有匹配成功,则返回 -1
eg.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
27public class Number {
private static int LinearSearch(int[] list,int key) {
for(int i = 0;i < list.length;i++){
if(key == list[i]){
return i;
}
}
return -1;
}
public static void main(String[] args) {
int[] list = {1, 3, 5, 7, -3};
int number1 = LinearSearch(list, 1);
int number2 = LinearSearch(list, 7);
int number3 = LinearSearch(list, -5);
System.out.println(number1);
System.out.println(number2);
System.out.println(number3);
}
}
//输出结果
0
3
-1
线性查找法把关键字和数组中的每一个元素进行比较,效率不高
二分查找法
使用二分查找法的前提条件是数组中的元素必须已经排好序,假设数组已经按升序排,二分查找法首先将关键字与数组的中间元素进行比较,考虑下面三种情况:
- 如果关键字小于中间元素,只需要在数组的前一半元素中继续查找关键字
- 如果关键字等于中间元素,则匹配成功,查找结束
- 如果关键字大于中间元素,只需要在数组的后一半元素中继续查找关键字
eg.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
39public class Number {
private static int binarySearch(int[] list,int key) {
int low = 0;
int high = list.length - 1;
//直到low > high时还没找到关键字就结束查找,返回 -1
while(low <= high){
int mid = (low + high)/2;
if(key < list[mid]){
high = mid - 1;
}
else if(key > list[mid]){
low = mid + 1;
}
else if(key == list[mid]){
return mid;
}
}
return -1;
}
public static void main(String[] args) {
int[] list = {1,3,5,7,9,10,11,13,15,17};
int number1 = binarySearch(list,7);
int number2 = binarySearch(list,11);
int number3 = binarySearch(list,23);
System.out.println(number1);
System.out.println(number2);
System.out.println(number3);
}
}
//输出结果
3
6
-1
数组排序
eg.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
29import java.util.Arrays;
import java.util.Collections;
public class Number {
public static void main(String[] args) {
//升序排序
//定义一个整型数组
int[] scores = { 78, 93, 84, 64 };
//使用 Arrays 类的 sort() 方法对数组进行升序排序
Arrays.sort(scores);
System.out.println("升序排序后数组中元素的值:");
System.out.println(Arrays.toString(scores));
//倒序排序
//这里必须把 int 类型写成 Integer 类型才能通过
Integer [] scores1 = { 78, 93, 84, 64 };
//使用 Arrays 类的 sort() 方法对数组进行倒序排序
Arrays.sort(scores1,Collections.reverseOrder());
System.out.println("倒序排序后数组中元素的值:");
System.out.println(Arrays.toString(scores1));
}
}
//输出结果
升序排序后数组中元素的值:
[64, 78, 84, 93]
倒序排序后数组中元素的值:
[93, 84, 78, 64]
Arrays 类
java.util.Arrays 类能方便地操作数组,它提供的所有方法都是静态的
导入1
import java.util.Arrays;
- 给数组赋值:通过 fill 方法
- 对数组排序:通过 sort 方法,按升序
- 比较数组:通过 equals 方法比较数组中元素值是否相等
- 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作
1
2
3
4//用二分查找算法在给定数组中搜索给定值的对象
public static int binarySearch(Object[] a, Object key)
//导入包之后引用:
Arrays.binarySearch(Object[] a, Object key);
1 | //如果两个指定的 long 型数组彼此相等,则返回 true |
1 | //填充数组 |
多维数组
新建一个二维数组1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16public class Number {
public static void main(String[] args) {
int [][] a = {{2, 6, 8},{7, 3, 9}};
//访问二维数组的长度
System.out.println(a[0].length);
//打印数组,for 循环
for (int row = 0; row < a.length ; row++){
for (int column = 0; column < a[row].length ; column++){
System.out.println(a[row][column] + " ");
}
System.out.println();
}
}
}
数组线性表 ArrayList 类
Java 提供 ArrayList 类来存储不限定个数的对象
优点:
- 容量不固定(有一个较大的最大阈值)
- 有序的(与输入顺序一致)
- 元素可以为 null
- 效率高
- 占用空间更小
ArrayList 中的一些方法:1
2
3
4
5
6
7
8
9
10
11ArrayList() 创建一个空的线性表
add(o: Object): void 在这个线性表的末尾追加一个新元素 0
add(index: int, o:Object): void 在这个线性表的特定下标处增加一个新元素 0
clear(): void 从这个线性表中删除所有的元素
contains(o:Object): boolean 如果这个线性表包含元素 0 则返回 true
get(index: int): Object 返回这个线性表在特定下标处的元素
indexOf(o:Object): int 返回这个线性表中第一个匹配元素的下标
isEmpty(): boolean 如果这个线性表不包含元素则返回 true
lastIndexOf(o:Object): int 返回这个线性表中最后一个匹配元素的下标
remove(o:Object): boolean 删除指定下标处的元素
set(index: int, o:Object): Object 设置在特定下标处的元素
eg.使用 ArrayList 存储对象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
41import java.util.ArrayList;
public class Array {
public static void main(String[] args) {
ArrayList cityList = new ArrayList();
cityList.add("Hongkong");
cityList.add("London");
cityList.add("Paris");
System.out.println("数组大小: " + cityList.size());
System.out.println("HongKong 在数组里吗? " + cityList.contains("Hongkong"));
System.out.println("HongKong 在数组的哪个位置: " + cityList.indexOf("Hongkong"));
System.out.println("这个数组是空的吗? " + cityList.isEmpty());
//在数组第 2 的位置增加 Guangdong
cityList.add(2,"Guangdong");
//移除 London
cityList.remove("London");
//移除 Paris
cityList.remove(2);
//以字符串形式输出数组
System.out.println(cityList.toString());
//for 循环遍历数组
for (int i = cityList.size() - 1; i>=0;i--) {
System.out.println(cityList.get(i) + " ");
}
}
}
//输出结果
数组大小: 3
HongKong 在数组里吗? true
HongKong 在数组的哪个位置: 0
这个数组是空的吗? false
[Hongkong, Guangdong]
Guangdong
Hongkong
数组和 ArrayList 之间的异同
可以像使用数组一样使用 ArrayList 对象,但是两者还是有很多不同之处
一旦创建了一个数组,它的大小就确定下来了。可以使用方括号访问数组元素(eg. a[index])。当创建 ArrayList 后,它的大小为 0 。如果元素不在线性表中,就不能使用 get 和 set 方法。向线性表中添加,插入和删除元素是比较容易的,而向数组中添加、插入和删除元素是比较复杂的。为了实现这些操作,必须编写代码操纵这个数组
1 | 操作 数组 ArrayList |