数组

扫码查看

一、数组的概念

  • 数组概念: 数组就是用于存储数据的长度固定的容器,保证多个数据的数据类型要一致。

百度百科中对数组的定义:

所谓数组(array),就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,以便统一管理他们,然后用编号区分他们,这个名字称为数组名,编号称为下标或索引(index)。组成数组的各个变量称为数组的元素(element)。数组中元素的个数称为数组的长度(length)。

数组的特点:

1、数组的长度一旦确定就不能修改

2、创建数组时会在内存中开辟一整块连续的空间

3、存取元素的速度快,因为可以通过[下标],直接定位到任意一个元素

二、数组的声明与初始化

//推荐
元素的数据类型[] 二维数组的名称;

//不推荐
元素的数据类型  二维数组名[];

方式一:静态初始化

数据类型[] 数组名 = {元素1,元素2,元素3...};//必须在一个语句中完成,不能分开两个语句写

方式二:静态初始化

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

方式三:动态初始化

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

数组定义格式详解:

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

  • 元素的类型可以是任意的Java的数据类型。例如:int, String, Student等

  • [] : 表示数组

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

  • new:关键字,创建数组使用的关键字。因为数组本身是引用数据类型,所以要用new创建数组对象

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

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

    • 和水杯道理相同,买了一个2升的水杯,总容量就是2升,不能多也不能少

三、数组元素的访问

  • 索引: 每一个存储到数组的元素,都会自动的拥有一个编号,从0开始,这个自动编号称为数组索引(index),可以通过数组的索引访问到数组中的元素。

  • 索引范围:[0, 数组的长度-1]

数组名[索引]
  • 索引访问数组中的元素:
    • 数组名[索引]=数值,为数组中的元素赋值

    • 变量=数组名[索引],获取出数组中的元素

  1 public static void main(String[] args) {
  2     //定义存储int类型数组,赋值元素1,2,3,4,5
  3     int[] arr = {1,2,3,4,5};
  4     //为0索引元素赋值为6
  5     arr[0] = 6;
  6     //获取数组0索引上的元素
  7     int i = arr[0];
  8     System.out.println(i);
  9     //直接输出数组0索引元素
 10     System.out.println(arr[0]);
 11 }

四、数组的遍历

  • 数组的长度属性: 每个数组都具有长度,而且是固定的,Java中赋予了数组的一个属性,可以获取到数组的长度,语句为:数组名.length ,属性length的执行结果是数组的长度,int类型结果。由次可以推断出,数组的最大索引值为数组名.length-1

  • 数组遍历: 将数组中的每个元素分别获取出来,就是遍历。遍历也是数组操作中的基石

  1 public static void main(String[] args) {
  2   	int[] arr = new int[]{1,2,3,4,5};
  3   	//打印数组的属性,输出结果是5
  4   	System.out.println("数组的长度:" + arr.length);
  5
  6     //遍历输出数组中的元素
  7     System.out.println("数组的元素有:");
  8     for(int i=0; i<arr.length; i++){
  9         System.out.println(arr[i]);
 10     }
 11 }

五、数组元素的默认值

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

六、数组内存图

6.1 内存概述

内存是计算机中重要的部件之一,它是与CPU进行沟通的桥梁。其作用是用于暂时存放CPU中的运算数据,以及与硬盘等外部存储器交换的数据。只要计算机在运行中,CPU就会把需要运算的数据调到内存中进行运算,当运算完成后CPU再将结果传送出来。我们编写的程序是存放在硬盘中的,在硬盘中的程序是不会运行的,必须放进内存中才能运行,运行完毕后会清空内存。

Java虚拟机要运行程序,必须要对内存进行空间的分配和管理。

6.2 Java虚拟机的内存划分

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

区域名称作用
程序计数器程序计数器是CPU中的寄存器,它包含每一个线程下一条要执行的指令的地址
本地方法栈当程序中调用了native的本地方法时,本地方法执行期间的内存区域
方法区存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据
堆内存存储对象(包括数组对象),new来创建的,都存储在堆内存
虚拟机栈用于存储正在执行的每个Java方法的局部变量表等。局部变量表存放了编译期可知长度的各种基本数据类型、对象引用,方法执行完,自动释放

6.3 数组在内存中的存储

6.3.1 一个数组内存图

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

6.3.2 数组下标为什么是0开始

因为第一个元素距离数组首地址间隔0个单元

6.3.3 两个数组内存图

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

6.3.4 两个变量指向一个数组

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

七、二维数组

  • 二维数组:本质上就是元素为一维数组的一个数组。

  • 二维数组的标记:[][]

int[][] arr; //arr是一个二维数组,可以看成元素是int[]一维数组类型的一个数组

二维数组也可以看成一个二维表,行*列组成的二维表,只不过这个二维表,每一行的列数还可能不同。但是每一个单元格中的元素的数据类型是一致的,例如:都是int,都是String等

7.1 二维数组的声明与初始化

//推荐
元素的数据类型[][] 二维数组的名称;

//不推荐
元素的数据类型  二维数组名[][];
//不推荐
元素的数据类型[]  二维数组名[];

7.1.1 静态初始化

元素的数据类型[][] 二维数组名 = new 元素的数据类型[][]{
	{元素1,元素2,元素3 。。。},
	{第二行的值列表},
	...
	{第n行的值列表}
};

元素的数据类型[][] 二维数组名;
二维数组名 = new 元素的数据类型[][]{
	{元素1,元素2,元素3 。。。},
	{第二行的值列表},
	...
	{第n行的值列表}
};

//以下格式要求声明与静态初始化必须一起完成
元素的数据类型[][] 二维数组的名称 = {
	{元素1,元素2,元素3 。。。},
	{第二行的值列表},
	...
	{第n行的值列表}
};

7.1.2 动态初始化(规则二维表:每一行的列数是相同的)

//(1)确定行数和列数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[m][n];
	m:表示这个二维数组有多少个一维数组。或者说一共二维表有几行
	n:表示每一个一维数组的元素有多少个。或者说每一行共有一个单元格

//此时创建完数组,行数、列数确定,而且元素也都有默认值

//(2)再为元素赋新值
二维数组名[行下标][列下标] = 值;
  1 public static void main(String[] args) {
  2     //定义一个二维数组
  3     int[][] arr = new int[3][2];
  4
  5     //定义了一个二维数组arr
  6     //这个二维数组有3个一维数组的元素
  7     //每一个一维数组有2个元素
  8     //输出二维数组名称
  9     System.out.println(arr); //地址值	[[I@175078b
 10
 11     //输出二维数组的第一个元素一维数组的名称
 12     System.out.println(arr[0]); //地址值	[I@42552c
 13     System.out.println(arr[1]); //地址值	[I@e5bbd6
 14     System.out.println(arr[2]); //地址值	[I@8ee016
 15
 16     //输出二维数组的元素
 17     System.out.println(arr[0][0]); //0
 18     System.out.println(arr[0][1]); //0
 19
 20     //...
 21 }

7.1.3 动态初始化(不规则:每一行的列数可能不一样)

//(1)先确定总行数
元素的数据类型[][] 二维数组名 = new 元素的数据类型[总行数][];

//此时只是确定了总行数,每一行里面现在是null

//(2)再确定每一行的列数,创建每一行的一维数组
二维数组名[行下标] = new 元素的数据类型[该行的总列数];

//此时已经new完的行的元素就有默认值了,没有new的行还是null

//(3)再为元素赋值
二维数组名[行下标][列下标] = 值;
  1 public static void main(String[] args) {
  2 	//定义数组
  3 	int[][] arr = new int[3][];
  4
  5 	System.out.println(arr);	//[[I@175078b
  6
  7 	System.out.println(arr[1][0]);//NullPointerException
  8 	System.out.println(arr[0]); //null
  9 	System.out.println(arr[1]); //null
 10 	System.out.println(arr[2]); //null
 11
 12 	//动态的为每一个一维数组分配空间
 13 	arr[0] = new int[2];
 14 	arr[1] = new int[3];
 15 	arr[2] = new int[1];
 16
 17 	System.out.println(arr[0]); //[I@42552c
 18 	System.out.println(arr[1]); //[I@e5bbd6
 19 	System.out.println(arr[2]); //[I@8ee016
 20
 21 	System.out.println(arr[0][0]); //0
 22 	System.out.println(arr[0][1]); //0
 23 	//ArrayIndexOutOfBoundsException
 24 	//System.out.println(arr[0][2]); //错误
 25
 26 	arr[1][0] = 100;
 27 	arr[1][2] = 200;
 28 }

7.2 二维数组的相关名称及其表示方式

(1)二维数组的长度/行数:

二维数组名.length

(2)二维数组的某一行:

二维数组名[行下标]

行下标的范围:[0, 二维数组名.length-1]

(3)某一行的列数:

二维数组名[行下标].length

因为二维数组的每一行是一个一维数组

(4)某一个元素

二维数组名[行下标][列下标]

7.3 二维数组的遍历

  1 for(int i=0; i<二维数组名.length; i++){
  2 	for(int j=0; j<二维数组名[i].length; j++){
  3 		System.out.print(二维数组名[i][j]);
  4 	}
  5 	System.out.println();
  6 }

7.4 数组操作的常见异常

7.4.1 数组越界异常

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

创建数组,赋值3个元素,数组的索引就是0,1,2,没有3索引,因此不能访问数组中不存在的索引,程序运行后,将会抛出 ArrayIndexOutOfBoundsException 数组越界异常。在开发中,数组的越界异常是不能出现的,一旦出现了,就必须要修改编写的代码

7.4.2 数组空指针异常

  1 public static void main(String[] args) {
  2 	//定义数组
  3 	int[][] arr = new int[3][];
  4
  5 	System.out.println(arr[0][0]);//NullPointerException
  6 }

数组的每一行还未分配具体存储元素的空间,arr[0]是null,访问arr[0][0]会抛出NullPointerException 空指针异常

01-07 12:55
查看更多