java数组入门到进阶完整知识点


前言

每一种高级语言,我们都不可避免的要学习数组的相关知识,今天就跟着笔者来学习一下java的数组创建及相关使用吧,相信你学完一定有所收获!


提示:以下是本篇文章正文内容,下面案例可供参考
在这里插入图片描述

一、数组是什么?

数组是存储一组相同数据类型的数据集合。
数组本质上就是能让我们批量创建相同类型的变量。

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

在这里插入图片描述
和C语言一样,java中数组的下标也是从0开始,往后依次加1,你可以通过数组的下标来找到数组中的某个元素

二、数组的创建

静态初始化
数据类型[ ] 数组名称={初始化数据}
动态初始化
数据类型[ ] 数组名称=new 数组类型[ ]{初始化数据};

代码如下(示例):

public static void main(String[] args) {
    
    
        //法一:传统定义数组并初始化
        int[] arr={
    
    1,2,3};//int[]是一种类型,[]里不能加东西,否则会报错
        //这里没有写new,但实际也是一个对象

        //法二:用new,定义数组并未初始化
        int[] arr2=new int[3];//new是java的关键字,用来实例化java的对象,java的数组也是一个对象
        //对象,你可以想象成一个具体的实物
        //这句代码效果相当于int[] arr2={0,0,0}

        //法三:用new,定义数组并初始化
        int[] arr3=new int[]{
    
    1,2,3};//这里new int[],[]里也是不能加东西的
        //法三这个情况下,编译器也会认为,给了一个长度为3数组,里面存放1,2,3,效果和法一一样
    }

法一效果图:
在这里插入图片描述

法二效果图:
在这里插入图片描述
法三效果图:
在这里插入图片描述
ps1:静态初始化时,数组元素个数和初始化
数据的格式是一样的
ps2:int[]arr={1,2,3}也可以像C语言一样写成int arr[]={1,2,3},但我们还是建议写int[]arr={1,2,3},这样更方便理解,int[]是整形数组类型

三、数组的使用

1.计算数组长度

C语言中我们用 sizeof(数组名)/sizeof(数组元素类型)来计算数组的长度,但java中计算数组长度非常简单,我们直接用数组名.length即可
示例如下:

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

运行效果如下:
在这里插入图片描述

2.实现数组元素的访问

这个和C语言是一样的,比如你要访问数组里的第n个元素,直接数组名[n-1]即可,比如现在有1整形数组arr={1,2,3,4,5,6,7},下标分别是
0,1,2,3,4,5,6我现在要访问4这个元素,只要访问数组的第3个下标

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

运行后打印4
在这里插入图片描述
关于数组访问越界:访问下标超出可允许访问范围,比如arr={1,2,3}你可以访问的下标范围是0~2,如果你访问超出这个范围,比如arr[-1],这里会报错,因为你已经越界访问了,给你的那块空间是数组下标0往后到2的空间,你访问前面不属于你的地方,没有人知道当时那块空间在进行什么操作,你突然改变那块空间,可能造成严重后果。

3.遍历数组

1.一般for循环

public static void main(String[] args) {
    
    
        int[]arr={
    
    1,2,3,4,5,6};
        for(int i=0;i<arr.length;i++)
        {
    
    
            System.out.print(arr[i]+" ");
        }
    }

运行效果如下:
在这里插入图片描述
2.增强for循环(for each循环)
写法如下:for(类型名 变量名:数组名)
注意:这里的类型需要与数组元素类型相对应

public static void main(String[] args) {
    
    
        int[]arr={
    
    1,2,3,4,5,6};
        for(int x:arr){
    
    
        //for里面定义一个整形x来接收整形数组里的每一个数
            System.out.println(x+" ");
        }
    }

打印效果如下:
在这里插入图片描述
ps:for循环和for each循环的区别
for循环是可以拿到下标的,for each是不可以拿到下标的
比如,你要找的一个数字,然后返回下标,你肯定用普通的for循环。如果只是获取数组里的每个元素,肯定是for each更方便。
3.借助java工具类Arrays
Arrays是java中操作数组的工具类,要借助别人写好的工具类,我们需要打开相关的包import java.util.Arrays;,就像C语言调用一些函数需要#include<头文件>一样

import java.util.Arrays;
public static void main(String[] args) {
    
    
        int []arr={
    
    1,2,3,4,5,6,7};
        String ret= Arrays.toString(arr);
        //Arrays.toString(arr)是把数组变成一个字符串并返回,
        //我们用字符串类型的ret来接收
        System.out.println(ret);
        //如果你嫌写两行代码麻烦
        //直接写System.out.println(Arrays.toString(arr));也可以
    }

运行效果如下:
在这里插入图片描述

四、数组作为方法的参数

1.基本方法

要学习这块知识,我们需要知道数组的存储方式

public static void main(String[] args) {
    
    
        int[] array={
    
    1,2,3,4,5,6,7};
    }

在main函数中,array是一个局部变量,局部变量是放在栈里面的,而{1,2,3,4,5,6,7}则是作为一个对象存放在堆里,那你对象放堆里会有一个地址号,我们这里假设它的地址号是0x789,那么array里面存储的就是0x789。非常类似C语言的指针,也就是说array确实是一个变量,不管它存储的是堆里一个对象的地址。所以我们也称arr为“引用变量”,但毕竟我们学的是java不是C语言,所以我们不讨论指针解引用等问题。
在这里插入图片描述array是个引用变量,引用是用来指向一个对象的,需要注意的是也会有引用变量不指向任何对象,代码如下:

public static void main(String[] args) {
    
    
        int []arr=null;
        System.out.println(arr.length);//运行后会报错——空指针异常
        //因为你不指向任何对象嘛,又怎么来谈长度呢
    }

2.理解引用类型(重难点)

public static void hs1(int[]array1) {
    
    
        array1=new int[]{
    
    11,26,13,4,51,61};
    }

    public static void hs2(int[]array2) {
    
    
        array2[0]=211;
    }

    public static void main(String[] args) {
    
    
        int []array={
    
    1,2,3,4,5,6};
        System.out.println(Arrays.toString(array));//[1, 2, 3, 4, 5, 6]
        hs1(array);
        System.out.println(Arrays.toString(array));//[1, 2, 3, 4, 5, 6]
        hs2(array);
        System.out.println(Arrays.toString(array));//[211, 2, 3, 4, 5, 6]
    }

我们假设array指向的对象地址为0x123

关于hs1,我们进入hs1这个方法后,array把它指向的对象地址传给array1,array1里保存0x123,也就说刚进去hs1方法时,array1也指向{1,2,3,4,5,6}这个对象
在这里插入图片描述
但是后面 array1=new int[]{11,26,13,4,51,61};我们在堆里new了一个新的对象赋值给array1,我们假设新对象地址0x456,这时,array1就指向新的对象了
在这里插入图片描述
需要注意的是,这里的array1是形参,它并没有影响到实参array,你第二次打印的是实参array,所以还是打印[1, 2, 3, 4, 5, 6]

关于hs2,我们进入hs2之后,array把它指向的地址传给array2,也就是array2存放0x123,然后我们通过array2这个引用变量,找到它指向对象的下标为0的值1并将值1修改为899
在这里插入图片描述
hs2和hs1的区别是什么呢?hs2是通过形参的引用来改变引用变量所指向对象的值,hs1则是改变了形参所指向的对象,两者有本质区别

注意:一个引用只能有一个对象,不然就是"海王",海王是要被系统警告的哈
举个代码的例子:

public static void main(String[] args) {
    
    
        int []arr=new int[]{
    
    1,2,3,4,5};
        arr=new int[]{
    
    1};
        arr=new int[]{
    
    2};
        arr=new int[]{
    
    3};
        System.out.println(Arrays.toString(arr));//打印[3]
    }

说个大白话就是,你arr现在是一个小伙子,这个小伙子一开始有个数组对象{1,2,3,4,5},但是他们分手了;他又找了另一个数组对象{1},又分手了;后续又找了数组对象{2},分手了。最后他找到了真爱数组对象{3}。你能说他有错吗?不能,他又没同时和多个人谈恋爱,这不是很正常的吗?这个例子也能侧面告诉我们为啥引用变量可以找到他指向的对象,小伙子有他女朋友的联系方式这很正常吧。

ps:引用变量不一定在栈上
一个变量在不在栈上,是由你变量的性质决定的,如果是一个局部变量、实例成员变量就不一定在栈上了,但它们都可以引用变量。就好比不管你出生在哪个地方,你都有可能获得对象,不是说只有一个地方才有权利获得对象。

五、数组作为方法的返回值

代码示例:写一个方法,将数组内元素全部*2
法一:

public static void func(int[]array) {
    
    
        for(int i=0;i<array.length;i++)
        {
    
    
            array[i]*=2;
        }
    }
    public static void main(String[] args) {
    
    
        int []arr={
    
    1,2,3};
        func(arr);
        System.out.println(Arrays.toString(arr));
    }

引用变量arr指向对象{1,2,3},调用func方法,我们把实参arr保存的地址交给形参array,也就是说array也可以指向对象{1,2,3}。然后我们通过array下标实现对象的修改。

但是这样的扩大二倍是在原数组的基础上扩大二倍,也就说原数组被改变了

法二:

public static int[] func2(int []arr) {
    
    
       int []ret=new int[arr.length];
       for(int i=0;i<arr.length;i++)
       {
    
    
           ret[i]=2*arr[i];
       }
       return ret;
    }

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

引用变量arr指向一个对象{1,2,3},我们调用方法func2,对象{1,2,3}的地址交给了形参arr,然后我们new一个和arr相同大小的对象并交给ret,然后用arr里的数*2赋给ret数组,然后返回ret即可。
示意图如下:
在这里插入图片描述
这样就不会改变原数组的值。

法一法二打印效果均如下:
在这里插入图片描述

六、写一个自己的ToString函数

public static String myToString(int[] arr) {
    
    
        if(arr==null)
        {
    
    
            return null;
            //防止传过来的引用变量没有任何对象,
            //那也就没有后续的.length说法了
        }
        String str="[";
        for(int i=0;i<arr.length;i++)
        {
    
    
            str=str+arr[i]+",";
        }
        str=str+"]";
        return str;
    }

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

运行效果如下:
在这里插入图片描述

七、二维数组

二维数组本质上也是一维数组,只不过每个元素又是一个一维数组。
基本语法

数据类型[][]数组名称=new 数据类型[行数][列数]{
    
    初始化数据};

三种创建方法示例如下:

public static void main(String[] args) {
    
    
        //法一
        int[][]arr={
    
    {
    
    1,2,3},{
    
    4,5,6}};
        //java中不允许int[][]这个[][]里加数字,这是一种类型
        //另外,你不能直接写{1,2,3,2,3},必须你手动进行分行(加括号)

        //法二
        int[][]brr=new int[][]{
    
    {
    
    1,2,3},{
    
    4,5,6}};
        //这样的创建方式也可以,但和法一一样,new int[][],[][]里不能加指定数字

        //法三
        int[][]crr=new int[2][3];
        //如果不进行初始化只是new一个对象可以new int[2][3],
        // [][]里可以加数字(不然不知道你要开辟多大空间)
    }

打印二维数组的每个元素
虽然说是二维数组,但和C语言一样,n维数组的本质都是1维数组,只不过每个一位数组里的元素都是数组,示意图如下:

在这里插入图片描述
法一:

public static void main(String[] args) {
    
    
        int[][]arr={
    
    {
    
    1,2,3},{
    
    4,5,6}};
        System.out.println(arr.length);
        //打印2,说明arr这个二维数组里存放2个引用变量,分别指向两个对象
        //也印证了上图,二维数组arr中是保存了2个引用变量
        for(int i=0;i< arr.length;i++)
        //因为大多数情况int[][]是不告诉你有多少行多少列的,
        //arr.length可以快速计算出行数
        {
    
    
            for(int j=0;j<arr[i].length;j++)
                //arr[i]进去arr里,也就是arr里的一个引用变量,
                // 然后引用变量.length计算出它指向对象的长度,也就是列数
            {
    
    
                System.out.print(arr[i][j]+" ");
            }
            System.out.println();
        }
    }

打印效果如下:
在这里插入图片描述
法二:

public static void main(String[] args) {
    
    
        int[][]arr={
    
    {
    
    1,2,3},{
    
    4,5,6}};
        for(int[]ret:arr)//arr是一个一维数组,里存放2个引用变量,我们用一维数组ret来接受
        {
    
    
            for(int x:ret)//ret是一个一维数组,我们用x来接受数组里的数据
            {
    
    
                System.out.print(x+" ");
            }
            System.out.println();
        }
    }

打印效果如下:
在这里插入图片描述
法三:
用已有的库方法打印

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

在这里插入图片描述


# 后记 本篇文章结束了java数组创建、使用、及引用变量和对象的相关原理,下一期java专栏会更新java数组的例题实战,期待你的关注。

猜你喜欢

转载自blog.csdn.net/m0_57180439/article/details/121003433