Java SE(5)——数组
1.初始数组
1.1 数组存在的意义
假如我们要保存五个JavaSE的期末考试成绩并输出,按照之前学习的知识,我们一般会写出如下代码:
public static void main(String[] args) {int score1 = 60;int score2 = 61;int score3 = 62;int score4 = 63;int score5 = 64;System.out.println(score1);System.out.println(score2);System.out.println(score3);System.out.println(score4);System.out.println(score5);}
如果要保存全班同学的JavaSE期末考试成绩呢?还是按照上面的写法逐个定义成绩?那样的话不仅写代码很费劲,写出来的代码也很冗余。但我们仔细观察不难发现,上面定义的数据都是同一类型的。在Java中,有没有什么办法能够一次性保存多个相同类型的数据?这就是本文所要介绍的数组
1.2 什么是数组
概念:是一种用于存储多个相同类型元素的数据集合。比如现实马路旁的停车位,
在Java中,包含八个整形元素的数组,就像是上图中八个连在一起的停车位,从上图可以看出数组有如下特点:
- 数组在内存中是一段连续的空间
- 数组中的每个元素都有对应的下标/索引对应
那么,初始数组之后,在Java中如何创建数组并且初始化呢?
1.3 数组的创建&初始化
创建数组的语法格式: T[] 数组名 = new T[N]
- T:数组中存放元素的数据类型
- T[]:数组的类型
- 数组名:数组的名字,同时也是该数组的引用(下面再详细说)
- N:数组的长度,也是数组中能存放元素的最大数量
1.3.1 初始化方式
(1)动态初始化:创建数组时,直接指定数组的长度
int[] array = new int[10];
(2)静态初始化:创建数组时不指定数组的长度,而是直接指定数组中存放的具体数据
int[] array = new int[]{1,2,3,4,5,6,7,8,9,10};
注意:
- 静态初始化虽然没有直接指定长度,但是编译器在编译阶段会根据{}中的数据来推断数组
- {}中的数据类型必须和[]前的类型一致
- 静态初始化可以简写,如下:
int[] array = {1,2,3,4,5,6,7,8,9,10};
- 以下的创建方式是错误的:
意思是,不能既是动态初始化又是静态初始化,即便[]中的数字和{}中的内容数量一样也不行
1.3.2 数组未初始化
当数组未初始化时,数组中存放的数据类型不同,其默认赋值也不一样
基本类型 | 默认值 |
---|---|
byte | 0 |
short | 0 |
int | 0 |
long | 0 |
float | 0.0f |
double | 0 |
char | /u0000 |
boolean | FALSE |
引用类型 | 默认值 |
---|---|
String… | null |
1.4 数组的基本使用
数组元素的访问
上文已经介绍过,数组在内存中是一段连续的空间,每个元素都有唯一确定的下标/索引与之对应。并且数组的下标是从0开始,向后单调递增。所以,可以使用下标来访问数组中的元素,如下:
注意:
- 可以通过下标来快速访问数组中的任意元素
- 假设数组的长度为五,那么有效下标[0,5),访问的下标不能越界,否则会报错,如下
数组的遍历
所谓遍历,就是把数组中的每个元素访问一遍。访问是指某一种操作,可以是打印,也可以是修改。上面的图片展示的就是对数组的一种遍历方式,但是这种访问方式存在很大弊端,如果数组的长度是100,难道就使用System.out.println打印100次吗?
所以,下面介绍两种常用的方式:
(1)使用for循环
public static void main(String[] args) {int[] array = new int[]{1,2,3,4,5,6,7,8,9,10};for (int i = 0; i < 10; i++) {System.out.println(array[i]);}}
不过,上述这种方式仍然可以再优化一下,for循环的次数不用写死,可以根据数组长度来决定遍历次数
public static void main(String[] args) {int[] array = new int[]{1,2,3,4,5,6,7,8,9,10};for (int i = 0; i < array.length; i++) {System.out.println(array[i]);}}
(2)使用foreach循环
public static void main(String[] args) {int[] array = new int[]{1,2,3,4,5,6,7,8,9,10};for (int i : array) {System.out.println(i);}}
相较于for循环,foreach循环可以避免下标越界问题
2.数组本身是引用类型
2.1 基本类型变量与引用类型变量的区别
public static void main(String[] args) {int a = 100;int b = 200;int[] array = new int[]{1,2,3};}
在上述代码中,a、b、array,都是函数内部的变量,因此其空间都在main方法对应的栈帧中分配。a、b是内置类型的变量,因此其空间中保存的就是给该变量初始化的值
对于这段代码,在main方法中一共存在三个变量,它们在内存中的分布如下
从上图可以看到,引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始
地址。通过该地址,引用变量便可以去操作对象
2.2 认识null
null 在 Java 中表示 “空引用” , 也就是⼀个不指向对象的引用。不能对这个内存进行任何读写操作.,一旦尝试读写, 就会抛出 NullPointerException(空指针异常)
3.操作数组的部分方法
这里需要使用工具类Arrays中的部分方法
3.1 数组转字符串
public static void main(String[] args) {int[] array = new int[]{1,2,3,4,5,6,7,8,9,10};String string = Arrays.toString(array);System.out.println(string);}
将数组转换为字符串后,再打印就方便一些了
3.2 数组排序
public static void main(String[] args) {int[] array = new int[]{1,3,2,4,7,6,5,8,9,10};Arrays.sort(array);for(int cur : array) {System.out.print(cur + " ");}}
3.3 拷贝数组
public static void main(String[] args) {int[] array1 = new int[]{1,2,3,4,5,6,7,8,9,10};//将数组完整地拷贝一份int[] array2 = Arrays.copyOf(array1, array1.length);for(int cur : array2) {System.out.print(cur + " ");}System.out.println();System.out.println("========================================");//范围拷贝[1,9)左闭右开int[] array3 = Arrays.copyOfRange(array1, 1, 9);for(int cur : array3) {System.out.print(cur + " ");}}
4.二维数组
4.1 普通二维数组
⼆维数组本质上也就是⼀维数组,,只不过每个元素又是⼀个一维数组
语法格式:
数据类型[ ][ ] 数组名称 = new 数据类型[ ][ ]{};
int[][] array = {{1,2,3},{4,5,6},{7,8,9}};
上述二维数组的内存分布如下
4.2 不规则二维数组
不规则的⼆维数组指的是,二维数组的列在定义的时候,没有确定
int[][] array = new int[2][];
array[0] = new int[3];
array[1] = new int[5];
上述⼆维数组就不是⼀个规则的二维数组,第一行有三列,第二行有五列