JavaSE:数组

Posted Two_Fly

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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数组的使用以及,从内存的角度剖析使我们对数组的理解更加清晰,鉴于笔者水平有限,文章可能会出现一些错误,望大家多多批评指正!

以上是关于JavaSE:数组的主要内容,如果未能解决你的问题,请参考以下文章

VSCode自定义代码片段—— 数组的响应式方法

VSCode自定义代码片段10—— 数组的响应式方法

JavaSE基础知识—数组的应用(4.2数组的基本及高级使用)

[javaSE] 数组(排序-冒泡排序)

JavaSE7基础 遍历二维数组 for循环

JavaSE7基础 二维数组 杨辉三角