Java 提供了一个数据结构:数组,用于存储相同类型的元素的一个固定大小的连续集合。数组是用于存储数据的集合,但往往将数组认为是相同类型的变量的集合
数组是一种效率最高的存储和随机访问对象引用序列的方式,在性能要求较高的场景中优先考虑数组

一维数组

声明数组变量

首先必须声明数组变量,才能在程序中使用数组

1
2
3
4
dateType[] arrayRefVar;

eg.
double[] myList;

创建、处理数组

数量变量的声明和创建数组

1
2
3
4
5
6
7
8
dataType[] 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
26
public 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. 创建新数组,让原数组变量指向新数组

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package 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]
  2. 使用 ArrayList 代替数组,通过泛型 ArrayList 可以储存不同类型的对象

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    package 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
18
public 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
27
public 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
39
public 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
29
import 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
2
3
4
5
6
//如果两个指定的 long 型数组彼此相等,则返回 true
//如果两个数组包含相同数量的元素,并且两个数组中的所有相应元素对都是相等的
//则认为这两个数组是相等的
public static boolean equals(long[] a, long[] a2)
//导入包之后引用:
Arrays.equals(long[] a, long[] a2);
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
//填充数组
public static void fill(int[] a, int val)

//eg.
import java.util.Arrays;

public class Number {

public static void main(String[] args) {
int [] a = { 10, 20 , 36, 50};
//填充 a[1] 到 a[3-1] 为 8
Arrays.fill(a,1,3,8);
System.out.println(Arrays.toString(a));
//输出 [10, 8, 8, 50]
}
}


public class Number {

public static void main(String[] args) {
int [] a = { 10, 20 , 36, 50};
//全部填充为8
Arrays.fill(a,8);
System.out.println(Arrays.toString(a));
//输出 [8, 8, 8, 8]
}
}

多维数组

新建一个二维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public 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
11
ArrayList()                                 创建一个空的线性表
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
41
import 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
2
3
4
5
6
7
8
9
10
    操作                             数组                                  ArrayList
创建数组/ArrayList Object[] a = new Objext[10] ArrayList list = new ArrayList()
引用元素 a [index] list.get(index)
更新元素 a [index] = "Hongkong"; list.set(index,"Hongkong");
返回大小 a length list.size()
添加一个新元素 list.add("Hongkong")
插入一个新元素 list.add(index,"Hongkong")
删除一个元素 list.remove(index);
删除一个元素 list.remove(Object)
删除所有元素 list.clear()

 Comments