JavaSE数组超详讲解一次性 弄懂 数组问题

Posted 来自爪哇的bean

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaSE数组超详讲解一次性 弄懂 数组问题相关的知识,希望对你有一定的参考价值。

希望通过博客和大家相互交流,相互学习,如有错误,请评论区指正

数组是一组相同类型数据元素的集合,这些数据在内存中连续存放(含义和C语言相同,这里就不再啰嗦)

目录

一、定义数组

1. 静态初始化

2. 动态初始化

3. 二维数组的不规则定义

Java中的数组是在内存的什么地方呢?

注意

二、数组的长度与打印数组

三、数组作为方法的参数

传参

什么是引用 ?

null

 四、操作数组的工具类(java.util.Arrays)

1. Arrays.toString();

2. Arrays.copyOf();

3. Arrays.copyOfRange();

4. Arrays.clone();


一、定义数组

1. 静态初始化

数据类型[] 数组名称 =  初始化数据 ;
int[] arr = 1, 2, 3, 4, 5;
int[][] array = 1,2,3,4,5,6;

定义一个数组,里面5个元素,每个元素类型都是int 

2. 动态初始化

数据类型[] 数组名称 = new 数据类型 []  初始化数据 ;

eg1. 

int[] arr2 = new int[]1, 2, 3, 4, 5;
int[][] array2 = new int[][]1,2,3,4,5,6;

eg2.

int[] arr3 = new int[5];
int[][] array3 = new int[2][3];

动态初始化中通过 new 来实例化一个数组对象,里面一共有5个元素,每个元素类型都是int

前面的arr, arr2, arr3都是数组的名字,也就是变量名,等号右边的是数组对象

eg2中创建数组的时候并没有赋初值,那么它里面就是0(注意和C语言区分)

3. 二维数组的不规则定义

int[][] array3 = new int[2][];

 这里要和C语言区分,C语言中可以将数组的行省略,但是列不能省略

Java当中,数组行必须要有,列可以不写,但是列不能自动推导出来

这种定义就是说该数组有两行,有几列是不确定的,并且Java中的每行的列数是可以不同的,如下代码:

int[][] array3 = new int[2][];
array3[0] = new int[2];
array3[1] = new int[3];

Java中的数组是在内存的什么地方呢?

这个问题我们应该严谨的来回答,数组对象在上,但是数组变量arr,arr2,arr3在栈上,这看起来很别扭,但事实就是这样

8大基本类型,里面直接存放的就是我们要存的数据,在栈上,但arr属于引用类型,里面存放的是它所指向的对象的地址

我们通过以下图来说明

eg. int[] arr = new int[]1, 2, 3, 4, 5;

 我们可以来验证一下

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

运行结果:

注意

 这并不是堆中真正的地址,而是经过Java处理的

二、数组的长度与打印数组

Java是一门面向对象的语言,我们关注对象本身,在Java中数组的一个属性就是length,我们可以直接拿来用,如下代码:

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

打印数组

方式1:

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

 运行结果:

 打印二维数组:

public static void main(String[] args) 
    int[][] array = new int[][]1,2,3,4,5,6;
    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();
    

 

二维数组的内存布局和C语言还是有很大区别的,如下图所示:

方式2:

for (int e : arr) 
    System.out.print(e + " ");

 方式2中for循环中有一个 后面是要打印的数组,前面是将要打印的数组的元素类型

二维数组:

public static void main(String[] args) 
    int[][] array = new int[][]1,2,3,4,5,6;
    for (int[] cur : array) 
        for (int val : cur) 
            System.out.print(val + " ");
        
        System.out.println();
    

 

 方式3:

也可以将数组转化为字符串然后打印输出

import java.util.Arrays;
public static void main(String[] args) 
    int[] arr = new int[]1, 2, 3, 4, 5;
    String str = Arrays.toString(arr);
    System.out.println(str);

 

 二维数组:

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

 

 

三、数组作为方法的参数

传参

当我们用数组来传参的时候应该,应该要拿什么来接收呢?

数组变量其实就是个引用,我们传过去,直接拿数组变量来接收即可(避免了传整个数组过去,开销过大)

如下代码:

public static void print(int[] array) 
    for (int i : array) 
        System.out.print(i + " ");
    

public static void main(String[] args) 
    int[] arr = new int[]1, 2, 3, 4, 5;
    print(arr);

 图示:

 两个引用指向同一块内存

什么是引用 ?

引用其实就相当于C语言当中的指针,用来指向一块内存,我们通过引用可以找到这块内存或这个对象,并通过引用来对这个对象进行一些列操作

 如下图:

Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实只是将数组的地址传入到函数形参中,这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大)

null

C语言当中的指针当我们创建之后不想让它指向任何变量时,就会让它指向NULL,代表0x00000000地址处

那么在Java当中也有这种情况,我们让引用指向 null,但是这里的null并不是0x00000000地址处,而是空对象,让这个引用指向一个空对象

int[] arr = null;

相当于一个无效的引用

当我们对这个引用进行操作的时候就会出空指针异常(NullPointerException)

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

 四、操作数组的工具类(java.util.Arrays)

Java提供的操作数组的方法很多,在写代码时很方便

 用的时候要导入java.util.Arrays这个包

1. Arrays.toString();

将数组当中的数据转换为字符串

 在 IDEA 中可以看到Java对toString方法做了重载,可以使得它可以针对不同类型的数组进行操作

函数原型

static String toString(int[] a)

 Returns a string representation of the contents of the specified array

代码示例

import java.util.Arrays;
public class Demo2 
    public static void main(String[] args) 
        int[] arr = 1, 2, 3, 4, 5;
        String str = Arrays.toString(arr);
        System.out.println(str);
    

在这段代码中通过Arrays.toString();将arr数组中的数据转换成了字符串(非常方便)

运行结果:

 模拟实现

public static String toString(int[] arr) 
    String str = "[";
    for (int i = 0; i < arr.length - 1; i++) 
        str = str + arr[i] + ",";
    
    if (arr.length != 0) 
        str = str + arr[arr.length - 1];   // 对最后一个元素做特殊处理
    
    str = str + "]";
    return str;

其他类型的数组做重载处理就行

2. Arrays.copyOf();

也可以用System.arraycopy();

拷贝数组

这个方法并不是简单的进行了 arr = arr2这样的操作,而是创建一个新的对象,将原对象中的值拷贝到新对象中,这样的话修改原数组自然是不会影响新数组的值

函数原型 

static int[] copyOf(int[] original, int newLength)

 Copies the specified array, truncating or padding with zeros (if necessary) so the copy has the specified length.

代码示例:

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

通过调用Arrays.copyOf();完成数组的深度拷贝

 这个方法的第二个参数也可以比原数组长度大或小

若传入的newLength > arr.length则剩余部分全部用0来填充

若newLength < arr.length,则从头拷贝到指定长度

eg.

public static void main(String[] args) 
    int[] arr = 1,2,3,4,5;
    int[] arr2 = Arrays.copyOf(arr, 8);
    System.out.println(Arrays.toString(arr2));
    int[] arr3 = Arrays.copyOf(arr, 3);
    System.out.println(Arrays.toString(arr3));

 模拟实现

public static int[] copyOf(int[] arr, int newLength) 
    int[] array = new int[newLength];
    int minLength = arr.length < newLength ? arr.length : newLength;
    for (int i = 0; i < minLength; i++) 
        array[i] = arr[i];
    
    return array;

注意:数组下标不能越界,将3种情况要全部考虑进去

3. Arrays.copyOfRange();

拷贝数组的某个范围

函数原型

static int[] copyOfRange(int[] original, int from, int to)

Copies the specified range of the specified array into a new array

代码示例

public static void main(String[] args) 
    int[] arr = 1,2,3,4,5;
    int[] arr2 = Arrays.copyOfRange(arr, 0, 5);
    System.out.println(Arrays.toString(arr2));
    int[] arr3 = Arrays.copyOfRange(arr, 2, 8);
    System.out.println(Arrays.toString(arr3));
    int[] arr4 = Arrays.copyOfRange(arr, 0, 0);
    System.out.println(Arrays.toString(arr4));

运行结果:

 注意:Java中的范围基本上都是左闭右开区间

模拟实现

public static int[] copyOfRange(int[] arr, int fromIndex, int toIndex) 
    int[] newArray = new int[toIndex - fromIndex];
    int toIndexMin = arr.length < toIndex ? arr.length : toIndex;
    for (int i = fromIndex; i < toIndexMin; i++) 
        newArray[i - fromIndex] = arr[i];
    
    return newArray;

4. Arrays.clone();

产生了这个对象的一个副本(Object 的克隆方法)

这是一个浅拷贝

欢迎大家关注!!!

一起学习交流 !!!

让我们将编程进行到底!!!

--------------整理不易,请三连支持------------------

以上是关于JavaSE数组超详讲解一次性 弄懂 数组问题的主要内容,如果未能解决你的问题,请参考以下文章

C语言☀️函数超详讲解☀️(详细讲解+代码演示+图解)建议收藏

这一次,彻底弄懂 Promise 原理

JavaSE7基础 找到一维数组中指定数值(第一次出现)的索引值 do-while循环实现

完全弄懂后缀数组

10分钟弄懂javascript数组

一文弄懂数组的和