一:数组基本概念
(1)什么是数组
数组:可以看成是相同类型元素的一个集合,在内存中占据连续的空间,每个元素都有自己的编号(下标),起始位置下标为0
(2)数组的创建
Java中,创建数组的格式如下,其中
T
:数组中存放元素的类型T[]
:表示数组的类型N
:表述数组长度
T[] 数组名 = new T[N];
例如下面的例子
public class TestDemo {
public static void main(String[] args) {
//创建一个可以容纳10个int类型元素的数组
int[] arr1 = new int [10];
//创建一个可以容纳5个double类型元素的数组
double[] arr2 = new double[5];
//创建一个可以容纳3个字符串元素的数组
String[] arr3 = new String[3];
}
}
(3)数组是对象
Java是一门纯面向对象语言,所以在Java中一切皆对象,数组当然也不例外。当使用int[] arr1 = new int [10]
这样的语句创建了一个数组之后,其中arr1
就称之为引用变量,存储了对象的地址,它引用或指向了一个数组对象。使用 System.out.println(arr1)
打印该引用变量,结果显示
[
:表示这是数组类型I
:数组里面存储的是整型@1b6d3586
:这是数组地址的哈希值
(4)数组的初始化
注意:
- 不要用C语言的方式定义数组,也即不要出现类似于
int arr[] = {1, 2, 3}
这样的操作 - 如果不确定数组当中内容时,使用动态初始化,否则建议使用静态态初始化
- 如果没有对数组进行初始化,数组中元素有其默认值(基本类型如下表;引用类型默认为
null
)
A:动态初始化
动态初始化:创建数组时直接指定数组中元素的个数,例如
int[] array = new int[10];
B:静态初始化
静态初始化:在创建数组时不直接指定数据元素个数,而直接赋值具体数据,例如
- 静态初始化虽然没有指定数组的长度,但编译器在编译时会根据
{}
中元素个数来确定数组的长度 - 静态初始化时,
{}
中数据类型必须与[]前数据类型一致 - 静态初始化可以简写,直接省去后面的
new T[]
,即int[] arr1 = {1, 2, 3}
(不推荐这样写,因为关键字new
更能体现出对象这个含义,而且编译器本身还是会还原的)
public class TestDemo{
public static void main(String[] args) {
int[] arr1 = new int[]{0, 2, 4, 5, 6};
String[] arr2 = new String[]{"hello", "this", "world"};
}
}
(5)数组的使用
A:元素访问
数组元素访问:数组在内存中是一段连续的空间,空间的编号都是从0开始的,然后依次递增,该编号称为数组的下标。数组可以通过下标访问其任意位置的元素。下标取值范围为:[0, N)
,其中N为元素个数,访问时下标不能大于等于N,否则编译器会报越界错误。如下:
public class TestDemo{
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3};
System.out.println(arr[1]);
System.out.println(arr[3]);//越界
}
}
B:遍历数组
遍历数组:遍历是指将数组中的所有元素都访问一遍同时执行某种操作(例如最简单的打印)。遍历数组时需要数组的长度,所以可以使用数组对象.length
的方式获取。例如
public class TestDemo{
public static void main(String[] args) {
int[] arr = new int[]{11, 22, 33, 44, 55, 66, 77};
for(int i = 0; i < arr.length; i++){
arr[i] *= 2;
System.out.print(arr[i]+" ");
}
}
}
二:通过数组深入理解Java中的引用类型
(1)JVM内存分布
和C/C++类似,为了对内存进行合理分配和管理,JVM会将内存按照如下逻辑划分
- 程序计数器PC:占据极小的空间,用于保存下一条待执行的指令的地址
- 虚拟机栈:每个方法在执行时,都会创建一个栈帧,栈帧会保存与该方法相关的信息(例如局部变量);方法运行结束后,栈帧自动销毁,相应数据也随之销毁
- 本地方法栈:与虚拟机栈作用类似,只不过保存的内容是本地方法的局部变量
- 堆:这是JVM所管理的最大内存区域。我们使用
new
创建的对象都是保存在堆上的。堆的生命周期和程序的生命周期一致 - 方法区:用于存储已经被虚拟机加载的类信息、常量、静态变量、既时编译器编译后的代码等数据。其中字节码就会保存在此区域
(2)基本类型变量与引用类型变量
基本类型变量:基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值
引用类型变量:引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。它类似于C/C++中的指针
有如下代码,其变量在内存中的分布情况如下图所示
public class TestDemo {
public static void main(String[] args) {
int a = 10;
int b = 20;
int[] arr = new int[]{1, 2, 3};
}
}
如果具有C/C++中指针基础,那么引用变量学习起来应该是没有任何问题的,下面的例子也生动的展示了引用的作用
public class TestDemo {
public static void main(String[] args) {
//定义一个引用变量arr1指向数组
int[] arr1 = new int[3];
//利用该引用变量操作数组
arr1[0] = 10;
arr1[1] = 20;
arr1[2] = 30;
int[] arr2 = new int[]{1, 2, 3, 4, 5};
arr2[0] = 100;
arr2[1] = 200;
//重点:让arr1指向arr2,然后arr1修改arr2数组
arr1 = arr2;
arr1[2] = 300;
arr1[3] = 400;
arr1[4] = 500;
for(int i = 0 ; i < arr2.length; i++){
System.out.println(arr2[i]);
}
}
}
(3)null
Java中使用null
代表空引用,表示该引用变量不指向任何对象
- 注意:如果对空引用进行任何读写操作汇报
NullPointerException
错误
int[] arr = null;
三:数组应用场景
(1)保存数据
略
(2)作为方法的参数
前面说过,对于基本类型,在传递参数时是传值,也即形参并不会影响到实参。而数组这种引用类型在传参时是传引用,也即形参会直接操作实参
public class TestDemo {
public static void modif(int[] arr1){
arr1[0] = 100;
}
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3};
System.out.println("修改前:" + arr[0]);
modif(arr);
System.out.println("修改后:" + arr[0]);
}
}
(3)作为方法的返回值
Java中,数组也可以方法的返回值,如下
public class TestDemo {
public static int[] test(){
int[] temp = {1, 2, 3, 4, 5};
return temp;
}
public static void main(String[] args) {
int[] ret = test();
for(int i = 0; i < ret.length; i++){
System.out.println(ret[i]);
}
}
}
四:二维数组
(1)二维数组
Java中二维数组定义方式如下
public class TestDemo {
public static void main(String[] args) {
//常见
int[][] arr1 = {{1, 2, 3,}, {4, 5, 6}};
int[][] arr2 = new int[2][3];
int[][] arr3 = new int[][]{{1, 2, 3,}, {4, 5, 6}};
//不规则数组
int[][] arr4 = new int[2][];
arr4[0] = new int[3];
arr4[1] = new int[5];
for(int i = 0; i < arr1.length; i++){
for(int j = 0; j < arr1[i].length; j++){
System.out.print(arr1[i][j] + " ");
}
System.out.println();
}
}
}
二维数组本质还是一维数组,只不过其每个元素都是一维的,所以遍历时还可以这样写
public class TestDemo {
public static void main(String[] args) {
int[][] arr1 = {{1, 2, 3,}, {4, 5, 6}};
for(int[] tmp : arr1){
for(int x : tmp){
System.out.print(x + " ");
}
System.out.println();
}
}
}
评论区