Java基础——数组

本文详细介绍了Java中的数组概念、内存布局、初始化方法、数组长度获取、元素访问以及数组的动态扩展与收缩,包括数组下标规则、二维数组、数组元素默认值、赋值规则和垃圾回收机制。后续还将涉及查找、排序等操作。
摘要由CSDN通过智能技术生成
  • 数组是一种引用数据类型,数组中的元素可以是任何数据类型【包括基本数据类型和引用数据类型】。
    1. Java中的容器:数组、集合框架。----是在内存中对多个数据的存储,而非磁盘上。
    2. 声明1:double[ ]= prices;  静态初始化【数组变量的赋值和数组元素的赋值同时操作】:prices =new double[ ] {20,32,43};
    3. 声明2:String[ ] =foods; 初始化:动态初始化:foods= new String[4]; //4代表数组的长度。
    4. 其他方式:上面的可以写成一行即,int[ ] arr = new int[4]。 int arr[ ] =new int[4];int[ ] arr ={1,2,3,4}。都是正确的。
    5. 数组的长度:foods.length。
    6. 数组的调用:foods[0],foods[1]。
    7. 数组一旦初始化,其长度就是确定的。!!!和数组扩容有关。
  • 数组元素默认值 

  • 一维数组内存解析 
    1. 一般,将内存区域划分为5个:程序计数器、虚拟机栈、本地方法栈、堆、方法区。
    2. 与数组相关的内存结构:虚拟机栈+堆。
    3. 例如,int[ ] arr = new int[ ] {1,2,3}。虚拟机栈:存放方法中声明的局部变量【实际是首地址】。比如 arr。堆:存放数组实体(即数组所有元素)。比如,1,2,3。
    4. 只要出现new,堆中就会新开辟一块。
    5. 若只是int[ ] arr1 = arr。相当于只是把arr的首地址赋值给arr1,并不会再在堆中新开辟一块,本质上是同一个数组。具体如下图。

  • 程序执行流程 

Q:为什么数组下标从0开始? 

         因为第一个元素距离数组首地址间隔0个单元格。下标表示的其实是偏移量。

  • 二维数组 

    1. 声明和初始化:静态初始化,int [ ][ ] arr2 =new int[ ][ ]{{1,2,3},{4,5,6},{7,8,9,10}};动态初始化1,int [ ][ ] arr3 =new int[3][4]; 动态初始化2:int [ ][ ] arr4=new int[3][ ]。
    2. 其它正确的写法:一、int arr5[ ][ ] =new int [ ][ ]{{1,2,3},{4,5,6},{7,8,9}}; 二、int [ ] arr6[ ] =new int[ ][ ] {{1,2,3},{4,5,6},{7,8,9}};  三、int arr7={{1,2,3},{4,5,6},{7,8,9}}。
    3. 如果初始化是动态初始化2的方式:int [ ][ ] arr4=new int[3][ ],那列数不确定的情况下,可以每一行进行初始化,即arr4[0] =new arr4[ ]{5,5,5}或者arr4[0]=new int[3]。
    4. 数组元素调用:调用内层:arr2[0][0]。调用外层:arr2[0]//打印出来的是{1,2,3}的地址
    5. 二维数组的长度:arr2.length=3、arr2[2].length=4。
    6. 如何遍历数组?以arr2举例。

for(int i=0; i<arr2.length; i++){
            for(int j=0; j<arr2[i].length; j++){
                System.out.print(arr2[i][j] + " ");
            }
            System.out.println();
        } 

  • 二维数组默认初始化值
    1. 以动态初始化1为根据:外层元素默认值arr3[0]:默认存储地址值(也包括了类型)。内层元素默认值:不同数据类型同一维。具体可看上面表格。
    2. 以动态初始化2为根据:外层元素默认值:null(因为数组也属于引用类型)内层元素默认值:数组元素不存在,报空指针异常。
  • 二维数组内存解析 

                                                              打叉的会被GC回收! 

  • 数组之间的赋值 
    • 数组之间相互赋值必须满足:维数一样、类型一样。二维和一维之间不能单纯的赋值。

举例:声明:int[] x,y[]; 在给x,y变量赋值以后,以下选项允许通过编译的是:【x是一维,y是二维】

a)    x[0] = y;                 //no
b)    y[0] = x;                 //yes
c)    y[0][0] = x;              //no
d)    x[0][0] = y;              //no
e)    y[0][0] = x[0];           //yes
f)    x = y;                    //no

提示:
一维数组:int[] x  或者int x[]   
二维数组:int[][] y 或者  int[] y[]  或者 int  y[][]

  • 数组的反转(拓展 数组对称) 
    • 此时注意反转要到什么时候结束?当交换 数组.length/2次时,停止交换。
    • arr[i]和arr[arr.length-1-i]做交换。
  • 数组的扩容 

                此部分在集合中会详细讲解。

        现有数组 int[] arr = new int[]{1,2,3,4,5}; ,现将数组长度扩容1倍,并将10,20,30三个数据添加到arr数组中,如何操作?

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

        //1、扩容1倍容量。       

        int[] newArr = new int[arr.length << 1];

        

        //2、将原有数组元素复制到新数组中。

        for(int i = 0;i < arr.length;i++){
            newArr[i] = arr[i];
        }

        

        //3、将10,20,30,添加到新数组中

        newArr[arr.length] = 10;
        newArr[arr.length + 1] = 20;
        newArr[arr.length + 2] = 30;

        

        //4、将新的数组地址赋值给原有的数组变量。

        arr=newArr;

其中步骤4、内存分析如下:

        补:其中涉及到GC垃圾回收器,GC是通过指针是否存在来判定是否进行回收【可达性分析算法:判断堆空间是不是可达的,是否能被其它变量访问的,不能访问的则回收。但并不是立马就回收掉(因为GC由于回收时进行会判断指针是否存在,但有时用户程序可能还在执行中,可能会走走停停这种状态,此时若要让GC一直工作就得一直进行判断。。。不太理想。。),GC会等一等,等需要GC的时候就会回收掉。比如,又来了一块内存,但堆空间满了,这时候GC会进行回收。】。 

  • 数组的缩容 

例如,现有数组 int[] arr={1,2,3,4,5,6,7}。现需删除数组中索引为4的元素。

        不新建数组版:考虑将后面的元素赋值到它前一个。

1、将后面元素赋值到前一个

for (int i = delIndex; i < arr.length - 1; i++) {
            arr[i] = arr[i + 1];
        }
2、由于空余出来一个位置,将最后一个元素赋值为0.        

        arr[arr.length - 1] = 0;

        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

 

下一篇更新数组的查找、排序等算法操作。 嘻嘻嘻~加油,鹿小葵!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值