Java 数组

191 阅读4分钟

Java 数组

一组连续的存储空间,存储多个相同类型的值。

数组的创建

基本组成数据类型[] 数组名 = new 数据类型[长度]

  • 先声明,再分配空间: 数据类型[] 数组名; 数组名 = new 数据类型[长度]
  • 声明并分配空间: 数据类型[] 数组名 = new 数据类型[长度]
  • 声明并赋值(繁琐): 数据类型[] 数组名 = new 数据类型[]{value1, value2, value3}
  • 声明并赋值(简便): 数据类型[] 数组名 = {value1, value2, value3}

数组的组成

  • 数组中的每个格子被称为数组元素
  • 对元素的访问:赋值取值
  • 通过数组下标访问元素。
  • 访问数组语法:数组名[下标]

错误情况

  • 数组下标越界异常:java.lang.ArrayIndexOutOfBoundsException

数组的遍历

从头至尾,逐一对数组中的元素进行访问。

数组名.length可以获取数组长度

int[] arr = {2, 3, 4, 5, 6};
int length = arr.length;
System.out.print("[");
for (int i = 0; i < length; i++) {
    System.out.print(i == length - 1 ? arr[i] + "]" : arr[i] + ", ");
}

JDK 1.5之后,Java 提供了增强 for 循环,简化了数组和集合的遍历,但增强 for 有个缺点,就是不能通过下标来访问数组元素

int[] arr = {2, 3, 4, 5, 6};
for (int i : arr) {
    System.out.print(i + " ");
}

数组的内存

程序运行中有两块重要的存储空间:

  • 存储基本数据类型以及引用数据类型的地址。
  • 空间比较小,存储速度比较快;JDK 1.5 之前 256k;JDK 1.5之后 1M
  • 先进后出。

  • 存储引用类型的实际数据。
  • 空间比较大,存储速度比较慢。

数组属于引用类型,实际存储在堆中,栈中存储堆中数组的引用(地址)。

数组的扩容

创建数组时,必须显示指定长度,并在创建之后不可更改长度。

扩容思想

  • 创建大于原数组长度的新数组。
  • 将原数组中的元素依次复制到新数组中。
  • 把新数组地址赋值给原数组。

原数组中的元素依次复制到新数组中的几种常见方式

  • 通过循环将原数组中的元素添加到新数组中。
  • 通过System.arraycopy(原数组名, 原数组起始位置, 新数组名, 新数组名起始位置, 长度)
  • 通过数组类型 新数组名 = Arrays.copyOf(原数组名, 新数组长度)

数组的插入与删除

通过操作数组元素下标,将数组中的元素进行插入与删除。

插入元素

  • 首先确定插入元素的位置。
  • 如果在数组的末尾,未超出最大下标并且该数组容量够用,则直接插入。
  • 如果在数组头部和中间,则需要先将要插入位置以及该位置后面的元素进行后移操作。
int[] arr1 = new int[]{11, 22, 33, 44, 55, 0, 0, 0};
int size = 5;
Scanner input = new Scanner(System.in);
System.out.println("请输入要插入的位置");
int position = input.nextInt();
System.out.println("请输入要插入的数字");
int num = input.nextInt();
        
for(int i = size - 1; i >= position; i--) {
    arr1[i + 1] = arr1[i]
}
size++;
arr1[position] = num;
System.out.println(Arrays.toString(arr1));

删除元素

  • 如果删除末尾元素,则直接进行删除。
  • 否则删除后需要进行前移元素。
int[] arr1 = new int[]{11, 22, 33, 44, 55, 0, 0, 0};
int size = 5;
Scanner input = new Scanner(System.in);
System.out.println("请输入要删除的位置");
int position1 = input.nextInt();

for(int i = position1; i < size; i++) {
    arr1[i] = arr1[i + 1];
}
size--;
arr1[size + 1] = 0;
System.out.println(Arrays.toString(arr1));

数组类型参数

  1. 基本数据类型参数:值传递

  2. 引用数据类型参数:地址值传递

数组类型返回值

调用数组类型返回值的方法时,方法执行后,返回的是数组的地址。

可变长参数

可接收多个同类型的实参,个数不限,使用方式与数组相同。

语法void 方法名(数据类型... 形参名){}

数组排序

冒泡排序

static void bubbleSort(int[] arr) {
    int length = arr.length;
    for (int i = 0; i < length - 1; i++) {
        for (int j = 0; j < length - 1 - i; j++) {
            if (arr[j + 1] < arr[j]) {
            int temp = arr[j];
            arr[j] = arr[j + 1];
            arr[j + 1] = temp;                    
            }
        }
    }
}

快速排序

private static void selectSort(int[] arr) {
    int length = arr.length;
    for (int i = 0; i < length - 1; i++) {
        for (int j = i + 1; j < length; j++) {
            if (arr[i] > arr[j]) {
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
            }
        }
    }
}

JDK 排序

JDK 1.5提供java.util.Arrays.sort(数组名)(只能升序)。

二维数组

一维数组中的一维数组;数组中的元素,还是数组。

高维数组中的每一个元素,保存了低维数组的地址

数组的创建

  • 先声明,再分配空间:
    数据类型[][] 数组名; 数组名 = new 数据类型[长度][长度]
  • 声明并分配空间:
    数据类型[][] 数组名 = new 数据类型[长度][长度]
    数据类型[][] 数组名 = new 数据类型[长度][]
  • 声明并赋值:
    数据类型[][] 数组名 = {{value1, value2, value3}, {value1, value2}, {value1}}

数组的使用

数组名[下标][下标]

数组的遍历

for (int i = 0; i < arr.length; i++) {
    for (int j = 0; j < arr[i].length; j++){
        System.out.print(arr[i][j] + " ");
    }
    System.out.println();
}