JavaSE:数组


数组

数组,我们可以理解为相同数据类型变量的集合,并且可以很方便的通过下标去访问和修改。

数组基础

数组的定义

三种数组创建的方法:以创建一个元素类型为int型的,由1,2,3,4,5组成的数组为例:

方法1:声明并赋值
    int[] arr = {1,2,3,4,5};

方法2:声明数组名开辟空间并且赋值
    int[] arr2 = new int[] {1,2,3,4,5};
方法3int[] arr = {1,2,3,4,5};//声明创建初始化
    int[] arr2 = new int[] {1,2,3,4,5};
    int[] arr3 = new int[5];
    arr3[0]=1;
    arr3[1]=2;
    arr3[2]=3;
    arr3[3]=4;
    arr3[4]=5;

在这里插入图片描述

注意事项:

1.定义数组时[]不可以写具体的数字

2.new关键字表示实例一个对象,Java中的数组也是一个对象,int[] arr = {1,2,3,4,5},虽然没写new但也实例了一个对象

数组的使用

数组的长度:数组的长度可以使用数组名.length得到

数组的访问:可以通过数组的下标去访问数组的每个元素,由于数组的下标是从0开始的,所以下标的范围只有(0 ~ 数组名.length-1),一旦访问的下标超过了这个范围,就会报如下错误:

在这里插入图片描述

数组的遍历

1.普通for循环(for — i循环)

public static void main(String[] args) {
    int[] arr = {1,2,3,4,5};//声明创建初始化
    for (int i = 0; i < arr.length; i++) {
        System.out.print(arr[i]+" ");
    }
}

在这里插入图片描述

2.增强for循环(for — each循环)

public static void main(String[] args) {
    int[] arr = {1,2,3,4,5};//声明创建初始化
    for (int x: arr) {
        System.out.print(x+" ");
    }
}

在这里插入图片描述

for—each的注意事项

1.for—each不能完成对数组值的修改,如上例所示,x只是一个用来临时储存arr[i]的局部变量,对x赋值只是对局部变量的赋值,并不会对arr[i]赋值

2.for—each 循环时取不到数组的下标

数组与方法

数组原理剖析

以下是Java的内存布局:
在这里插入图片描述

在我们理解Java数组时,主要是涉及到栈内存与堆内存的互相配合,我们以上述例子为例,着重讲一下Java数组

public static int sumArray(int[] arr) {
        int sum = 0;
        for (int i = 0; i < arr.length; i++) {
            sum+=arr[i];
        }
        return sum;
    }

public static void main(String[] args) {
    int[] arr = {1,2,3,4,5};//声明创建初始化
    System.out.println("数组元素的和为:"+sumArray(arr));
}

在这里插入图片描述

Java引用的分析

引用相当于一个 “别名”,也可以理解成一个指针,创建一个引用只是相当于创建了一个很小的变量,这个变量保存了内存中的一个地址,在逻辑上可以理解为指向了内存中的一个对象

案例分析1:

public static void arrayDouble1(int[] arr) {
    for (int i = 0; i < arr.length; i++) {
        arr[i]=arr[i]*2;
    }
}
public static void main(String[] args) {
    int[] arr = {1,2,3,4,5};
    arrayDouble1(arr);
    System.out.println(Arrays.toString(arr));
    //Arrays.toString(数组名):按字符串形式打印数组
}

在这里插入图片描述

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

在这里插入图片描述

两种都是想把原来的arr数组元素变成原来的2倍,为什么方法2没达到效果呢?我们从内存的角度分析一下

在这里插入图片描述

引用的指向

引用指向引用的对象

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

在这里插入图片描述

引用指向空null

在Java中,null表示空引用,不指向任何的对象,类似C语言中的空指针NULL,都表示一个无效的内存地址,因此不可以对这个地址进行任何操作,否则会抛出异常。

public static void main(String[] args) {
    int[] arr = null;
    System.out.println(arr.length);
}

在这里插入图片描述

注意:

1.一个引用只能保存一个对象的地址,也即一个引用只能同时指向一个对象。

2.引用变量不一定都在栈上,在不在栈上是由该引用变量的性质决定的(以后详细分析)。

数组的拷贝

copyOf

在这里插入图片描述

    public static void main(String[] args) {
       	int[] arr = {1,2,3,4,5};
        int[] newarr1 = Arrays.copyOf(arr,arr.length);
        int[] newarr2 = Arrays.copyOf(arr,arr.length*2);
        System.out.println(Arrays.toString(newarr1));
        System.out.println(Arrays.toString(newarr2));
    }

在这里插入图片描述

拷贝时给定的长度大于原始数组长度的那部分元素值均赋为0

copyOfRang

在这里插入图片描述

拷贝原数组的一部分,[from,to)参数表示要截取的原数组的下标范围,示例如下:

    public static void main(String[] args) {
        int[] arr = {1,2,3,4,5};
        int[] copyarr = Arrays.copyOfRange(arr,1,4);//对应原数组的下标范围:[1,4)
        System.out.println(Arrays.toString(copyarr));//[1,4)对应的元素为:2,3,4
    }

在这里插入图片描述

clone()方法

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

在这里插入图片描述

手动实现

public static int[] myCopyArrays(int[] arr) {
        int[] array = new int[arr.length];
        for (int i = 0; i < arr.length; i++) {
            array[i]=arr[i];
        }
        return array;
    }

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

在这里插入图片描述

二维数组

二维数组的定义

//方法1:        
int[][] array1 = {{1,2,3},{1,2,3}};
//方法2:        
int[][] array2 = new int[][]{{1,2,3},{1,2,3}};
//方法3:        
int[][] array3 = new int[2][3];//随后进行赋值

二维数组剖析

二维数组本质其实是一维数组,只是这个一维数组的每个元素都又是一个一维数组

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

在这里插入图片描述

二维数组使用

二维数组的行数与列数:根据我们对二维数组在内存上存储的剖析,我们可以轻易的理解为什么这样去求二维数组的行数与列数。

        int[][] array = {{1,2,3},{4,5,6}};
        System.out.println("二维数组的行数为:"+array.length);
        System.out.println("二维数组第一行的列数数为:"+array[0].length);
        System.out.println("二维数组第二行的列数数为:"+array[1].length);

在这里插入图片描述

二维数组的遍历:

        int[][] array = {{1,2,3},{4,5,6}};
        System.out.println("方法1:");
        for (int i = 0; i < array.length; i++) {
            for (int j = 0; j < array[i].length; j++) {
                System.out.print(array[i][j]+" ");
            }
            System.out.println();
        }
        System.out.println("方法2:");
        for (int[] ret: array) {
            for (int x: ret) {
                System.out.print(x+" ");
            }
            System.out.println();
        }

在这里插入图片描述

若要输出一个二维数组,除了采用以上两种遍历二维数组的方法外,还可以调用Arrays.deepToString(array)),其输出结果为:

在这里插入图片描述

不规则的二维数组

//方法1:        
int[][] array = {{1,2},{3,4,5}};
System.out.println("方法1:"+Arrays.deepToString(array));
//方法2:
int[][] array1 = new int[2][];
int[] arr1 = {1,2};
int[] arr2 = {3,4,5};
array1[0] = arr1;
array1[1] = arr2;
System.out.println("方法2:"+Arrays.deepToString(array1));

在这里插入图片描述

在这里插入图片描述

不规则数组的使用方式与规则二维数组基本相同

int[][] array1 = new int[2][];

在这里插入图片描述

未给array1赋值时,他的引用array1[0]和array1[1]均指向空null,故不可对其进行访问,否则会报如下错误。

在这里插入图片描述
本文详细分析了Java数组的使用以及,从内存的角度剖析使我们对数组的理解更加清晰,鉴于笔者水平有限,文章可能会出现一些错误,望大家多多批评指正!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值