JavaSE基础——(6)Java数组

目录

一、数组概述与定义

二、数组的初始化

2.1动态初始化

2.2 静态初始化

2.3数组越界异常和空指针异常

三、Java中堆和栈的区别

四、数组的查找

五、二维数组

六、Java中参数传递问题


一、数组概述与定义

数组是用来存储多个同种数据类型变量的一个容器集合。

存储的数据类型不仅可以包括基本数据类型,也可以存储引用数据类型。

 

数组定义的格式一般如下:

数据类型 [] 数据名=new 数据类型[数组长度]
or
数据类型 数据名[]=new 数据类型[数组长度]

 

二、数组的初始化

数组的初始化就是为数组开辟一段连续的内存空间,并且为每个数组元素赋予值。

初始化一般有两种方式:静态初始化和动态初始化。

2.1动态初始化

动态初始化的格式一般为:

int arr[]=new int[3];

动态初始化一般只指定数组的长度,而初始值则由系统给出:

  • 整数类型:byte、short、int、long默认初始化值都是0
  • 浮点类型:float、double默认初始化值都是0.0
  • 布尔类型:boolean默认初始化值为false
  • 字符类型:char默认初始化值为‘\u0000’

这里char的默认初始值为‘\u0000‘,‘\u’表示unicode编码,char在内存中占两个字节即16个二进制位,

而\u0000中的0位16进制的0,转换为二进制位0000,那么4个16进制的0就代表16个二进制位。

 

对上述整型的数组进行初始化之后,就可以通过arr这个名字访问数组的元素arr[i],

其中i为第i个元素的下标,i从0开始。

那我们直接输出arr这个变量,他存储的就是这个数组在内存空间存放的首地址:

"["的数量代表的是数组的维度,一维数组就有一个"[",二维数组就为"[[",以此类推;

“I”代表的是int类型的数组,同样"D"代表double型,"F"代表float型,"D"代表double型;

“@”为固定的标识符;

“@”后面的字符串代表的是地址值,是十六进制数来表达的。

 

2.2 静态初始化

静态初始化的格式一般如下:

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

比如:

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

注意在进行静态初始化中不能在中括号中指定数组的长度,

静态初始化会根据后面集合元素的个数自己确定数组的长度。

 

2.3数组越界异常和空指针异常

当使用静态或动态初始化数组的时候,如果访问不当可能会造成数组越界异常和空指针异常。

 

数组越界异常:当访问到申请数组长度大小之外的下标位置时,会引起数组越界异常。

比如如下代码:

public class Main {
    public static void main(String[] args){
        int a[]=new int[5];
        System.out.println(a[5]);
    }
}

其报错结果如下:

 

空指针异常:当动态申请的数组地址如果赋值给了空指针null,就无法在对该数组进行访问,否则会引起空指针异常。

比如以下代码:

public class Main {
    public static void main(String[] args){
        int a[]=new int[5];
        a=null;
        System.out.println(a[0]);
    }
}

其报错结果如下:

 

三、Java中堆和栈的区别

当Java进行代码编译时,会生成.class后缀的文件,然后将.class文件放入java虚拟机中进行运行,

虚拟机会根据变量创建的类型将变量放入内存中,具体存储规则如下:

  • 栈:存储的是局部变量,即定义在方法声明上和方法中的变量
  • 堆:存储new出来的数组或者对象

存储在栈空间的数据满足先进后出的原则,

存储在堆空间的数据满足

 

四、数组的查找

如果需要对数组中存储的元素进行访问,一般通过数组名+下标的形式,形如:

数据类型 变量名=数组名[下标]

我们以查找指定元素在数组中第一次出现的下标为例:

public class Main {
    public static void main(String[] args){
        int key=87;
        int a[]=new int[]{15,33,20,40,87};
        for(int i=0;i<a.length;i++){
            if(key==a[i]) {
                System.out.println(key + "在数组中下标为:" + i);
                return;
            }
        }
        System.out.println(key+"未出现在数组中");
    }
}

输出结果如下:

 

五、二维数组

二维数组即数组的数组,数组中存储的元素为数组,在线性代数中我们称为矩阵。

一般二维数组的定义如下:

int[][] arr=new int[2][3];
or
int arr[][]=new int[2][3];
or
int[] arr[]=new int[2][3];

其中中括号参数第一个2代表二维数组中有2个一维数组;

第二个3代表一维数组中有3个int类型数据。

同样我们使用下标对数组元素进行访问:

public class Main {
    public static void main(String[] args){
        int[][] a=new int[2][2];
        System.out.println(a);
        System.out.println(a[0]);
        System.out.println(a[0][0]);
    }
}

下面是输出结果:

第一个输出“[[I@1b6d3586”为二维数组的地址,

第二个输出“[I@4554617c”为二维数组的第一个一维数组的地址,

第三个输出“0”为二维数组中第一个一维数组的第一个元素的值。


我们还可以对二维数组进行直接赋值:

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

 

二维数组的遍历和一维数组相似,通过数组的下标来访问对应元素或者数组:

int element=arr[i][j]

其中i,j代表是第i个一维数组中第j个元素。

对二维数组进行遍历的代码如下:

public class Main {
    public static void main(String[] args){
        int[][] a={{1,2},{3,4},{5,6}};
        for(int i=0;i<3;i++){
            for(int j=0;j<2;j++)
                System.out.println(a[i][j]);
        }
    }
}

其结果如图所示:

 

六、Java中参数传递问题

参数传递是一个非常经典的问题,在多个编程语言中该问题都有涉及,这里我们测试普通数据类型int和数组数据来进行参数传递:

public class Main {
    public static void main(String[] args){
        int m=1;int n=2;
        exchange(m,n);
        System.out.println("m="+m+" n="+n);
        
        int[] a={1,2,3,4};
        exchange(a);
        for(int i=0;i<a.length;i++){
            System.out.print(a[i]+" ");
        }
    }
    public static void exchange(int m,int n){
        int temp=m;
        m=n;
        n=temp;
    }
    public static void exchange(int []a){
        int temp=a[0];
        a[0]=a[a.length-1];
        a[a.length-1]=temp;
    }
}

代码的功能是将两个int型数据作为参数传给方法exchange,在方法中进行两数互换,

然后回到main方法中对两数进行打印输出,得到的结果是两数并没有互换,还是原来的值,

第二个是将数组作为参数传给方法exchange,在方法中对数组的首尾元素进行互换,

然后回到main方法中对数组的元素进行打印输出,得到的结果是数组的首尾元素互换了,下面是输出结果:

 

从上述结果可知基本数据类型的值传递,不会改变原来的值,调用之后方法就会被弹栈,里面的局部变量也就消失了;

而数组这种引用数据类型的值传递,会改变原来的值,即使调用之后方法被贪占,但是堆内存储的数组对象依然存在,可以通过地址继续访问。

在Java中,参数的传递都是值传递,引用类型数据传递的值是地址值,所以方法内的操作会通过地址访问改变原值;

而基本数据类型就是变量值传递,不是地址值的传递,所以方法弹栈时局部变量被清空就不会改变原值。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值