数组

1.数组的概述

数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。

  • 数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。
  • 创建数组对象会在内存中开辟一整块连续的空间,而数组名中引用的是这块连续空间的首地址。
  • 数组的长度一旦确定,就不能修改。
  • 可以直接通过下标(或索引)的方式调用指定位置的元素,速度很快。
  • 数组的分类:
    • 按照维度:一维数组、二维数组、三维数组、…
    • 按照元素的数据类型分:基本数据类型元素的数组、引用数据类型元素的数组(即对象数组)

2.数组的定义

2.1 一维数组的定义

2.1.1 方式一

举例:

数组存储的数据类型[] 数组名字 = new 数组存储的数据类型[长度];

数组定义格式详解:

  • 数组存储的数据类型: 创建的数组容器可以存储什么数据类型。

  • [] : 表示数组。

  • 数组名字:为定义的数组起个变量名,满足标识符规范,可以使用名字操作数组。

  • new:关键字,创建数组使用的关键字。

  • 数组存储的数据类型: 创建的数组容器可以存储什么数据类型。

  • [长度]:数组的长度,表示数组容器中可以存储多少个元素。

注意:数组有定长特性,长度一旦指定,不可更改。

定义可以存储3个整数的数组容器,代码如下:

int[] arr = new int[3];

2.1.2 方式二

举例:

数据类型[] 数组名 = new 数据类型[]{元素1,元素2,元素3...};

定义存储1,2,3,4,5整数的数组容器。

int[] arr = new int[]{1,2,3,4,5};

2.1.3 方式三

举例:

数据类型[] 数组名 = {元素1,元素2,元素3...};

定义存储1,2,3,4,5整数的数组容器

定义存储12345整数的数组容器

2.2 二维数组的定义

//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];

3.数组的引用

  • 定义并用运算符new为之分配空间后,才可以引用数组中的每个元素
  • 数组元素的引用方式:数组名[数组元素下标]
    • 数组元素下标可以是整型常量或整型表达式。如a[3] , b[i] , c[6*i];
    • 数组元素下标从0开始;长度为n的数组合法下标取值范围: 0 —>n-1;如int a[]=new int[3]; 可引用的数组元素为a[0]、a[1]、a[2]
  • 每个数组都有一个属性length指明它的长度,例如:a.length 指明数组a的长度(元素个数)
    • 数组一旦初始化,其长度是不可变的

4.数组的初始化

**动态初始化:**数组声明且为数组元素分配空间与赋值的操作分开进行

**静态初始化:**在定义数组的同时就为数组元素分配空间并赋值。

数组是引用类型,它的元素相当于类的成员变量,因此数组一经分配空间,其中的每个元素也被按照成员变量同样的方式被隐式初始化。

public class Test {
public static void main(String argv[]){
	int a[]= new int[5];
	System.out.println(a[3]); //a[3]的默认值为0 
	} 
}

对于基本数据类型而言,默认初始化值各有不同

对于引用数据类型而言,默认初始化值为null(注意与0不同!)

2022-09-07_173143

5.数组的原理内存图

5.1 Java虚拟机的内存划分

为了提高运算效率,就对空间进行了不同区域的划分,因为每一片区域都有特定的处理数据方式和内存管理方式。JVM的内存划分:

区域名称作用
寄存器给CPU使用,和我们开发无关。
本地方法栈JVM在使用操作系统功能的时候使用,和我们开发无关。
方法区存储可以运行的class文件。
堆内存存储对象或者数组,new来创建的,都存储在堆内存。
方法栈方法运行时使用的内存,比如main方法运行,进入方法栈中执行。

5.2 数组在内存中的存储

一个数组内存图

public static void main(String[] args) { 
    int[] arr = new int[3]; 
    System.out.println(arr);//[I@5f150435 
}

以上方法执行,输出的结果是[I@5f150435,这个是什么呢?是数组在内存中的地址。new出来的内容,都是在堆

内存中存储的,而方法中的变量arr保存的是数组的地址。

输出arr[0],就会输出arr保存的内存地址中数组中0索引上的元素

2022-09-07_173941

两个数组内存图

public static void main(String[] args) { 
    int[] arr = new int[3]; 
    int[] arr2 = new int[2]; 
    System.out.println(arr); 
    System.out.println(arr2); 
}

2022-09-07_174128

两个变量指向一个数组

public static void main(String[] args) { 
    // 定义数组,存储3个元素 
    int[] arr = new int[3]; 
    //数组索引进行赋值 
    arr[0] = 5; arr[1] = 6; arr[2] = 7; 
    //输出3个索引上的元素值 
    System.out.println(arr[0]); 
    System.out.println(arr[1]); 
    System.out.println(arr[2]); 
    //定义数组变量arr2,将arr的地址赋值给arr2 
    int[] arr2 = arr; 
    arr2[1] = 9; 
    System.out.println(arr[1]); 
}

2022-09-07_174249

6.Arrays 工具类的使用

java.util.Arrays类即为操作数组的工具类,包含了用来操作数组(比如排序和搜索)的各种方法。

方法描述
boolean equals(int[] a,int[] b)判断两个数组是否相等。
String toString(int[] a)输出数组信息
void fill(int[] a,int val)将指定值填充到数组之中。
void sort(int[] a)对数组进行排序。
int binarySearch(int[] a,int key)对排序后的数组进行二分法检索指定的值。

7.数组使用中的常见异常

1.数组角标越界的异常:ArrayIndexOutOfBoundsException

访问到了数组不存在的角标发生

int[] arr = new int[2];
System.out.println(arr[2]);
System.out.println(arr[-1]);

2.空指针异常:NullPointerException

arr引用没有指向实体,却在操作实体中的元素

int[] arr = null;
System.out.println(arr[0]);