JAVA SE—— 数组(详细!!!)

Posted Perceus

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA SE—— 数组(详细!!!)相关的知识,希望对你有一定的参考价值。

@TOC


✨一、 数组基本用法

1.数组的作用

能让我们批量创建相同类型的变量


2.数组的创建

下面这三种创建方式都是可以的

int[] arr1=new int[] 1,2,3,4;

int[] arr2=1,2,3,4;

int[] arr3=new int[4];

3. 数组的使用

(1)获取长度

注意事项

代码示例:

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


(2)访问数组中的元素

注意事项:

代码示例:

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

    //获取数组中的元素的个数
    //System.out.println(array.length);

    //访问数组中的元素
     System.out.println(array[1]); // 执行结果: 2
     System.out.println(array[2]); // 执行结果: 3

    //修改数组中的元素 
    array[2] = 100; 

     System.out.println(array[2]); // 执行结果: 100


(3)下标越界

数组下标从0开始,范围是 [0,arr.length) ,左闭右开的区间,或者是[ 0,arr.length-1].

如果我们将下标的值超出数组的范围…

如下所示

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


(4)遍历数组(三种方法)

1.遍历方式(一)----- for循环

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

2.遍历方式(二)----> for-each

 public static void main(String[] args) 
        int[] arr = 1,2,3,4,5;
        for (int x:arr) 
            System.out.print(x+" ");
        
    

两种遍历的方式我们介绍完了,那么for循环和for-each有什么区别?


3.遍历方式(三)-----> 使用操作数组的工具类进行数组的打印(Arrays)

​ Arrays 就是操作Java数组的工具类,你要对数组做什么事情,就可以通过他来做,当然有些事情他是完成不了的.

 比如说:我们要打印数组,我们本来是用for循环 或者 for-each 来写的,但是我们也可以用Arrays的工具类打印.

 通过JDK的工具文档,我们查找到了相应的工具类.

代码如下:

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


⛲二、数组作为参数的方法

1.理解引用类型

(1)参数传内置类型

我们用 内置类型作为参数,进行交换变量,但是最后编译的结果 两个变量却并未发生交换.

这是为什么呢?

(2)参数传数组类型

结果:

我们用数组作为参数,进行交换变量,编译运行后,发现成功交换两个变量的值。此时数组名 arr 是一个 “引用”. 当传参的时候, 是按照引用传参.

那么为什么传引用类型可以 形参可对实参进行操作呢?

这里我们就要先从内存说起

数组在内存中的储存:

如下图:


总结:


(3)JVM内存区域划分

public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        int[] array =1,2,3,4,5;
        int a = 10;

    

array 和 a 都是局部变量,在栈上开辟空间
那么问题来了,a的空间里存的是 10,但是数组后面的数据,放在哪里?
和 10 一样放在栈上?
对象是存放在 堆上的

看一下JVM的5个部分

关于上面的划分方式, 后面慢慢理解. 此处我们重点理解 虚拟机 栈 和 堆.


(4)初始null

指针有空指针,那引用有空引用(引用里面存的地址是空的)吗?

public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        int[] array = 1,2,3,4,5;
        int[] array1 = null;
        //当一个引用被赋予null,就代表这该引用不指向任何对象
        // 既然该引用不指向任何对象,那么我这样写代码会怎么样?
        System.out.println(array1.length);
        // 求一个空引用所指向的对象的长度,但是空引用不会指向任何一个对象的
        // 何来的长度?那么代码运行的效果如何?
         图14,由图可知该写法是错误的,另外引用被指为null,堆上是不会分配内存给它的
        // 意思是你都不创建任何对象,你还想拿我空间,疯了?

        System.out.println(array1[0]);
        // 这个写法毫无疑问也是错的,没对象,你怎么访问对象里的东西?
    


⛹️‍三、数组作为方法的返回值

代码示例:

    public static void main(String[] args) 
        int[] arr = 1, 2, 3;
        transform(arr);
        printArray(arr);
    
    public static void printArray(int[] arr) 
        for (int i = 0; i < arr.length; i++) 
            System.out.println(arr[i]); 
    
    public static void transform(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;
        int[] output = transform(arr);
        printArray(output);
    
    public static void printArray(int[] arr) 
        for (int i = 0; i < arr.length; i++) 
            System.out.println(arr[i]);
        
    
    public static int[] transform(int[] arr) 
        int[] ret = new int[arr.length];
        for (int i = 0; i < arr.length; i++) 
            ret[i] = arr[i] * 2;
        
        return ret;
    


※思考题※

题目一:输出是什么

import java.util.Arrays;
public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        int[] array = 1,2,3,4,5;
        func1(array);
        System.out.println(Arrays.toString(array));// 图 18

    
    public static void func1(int[] array)
        array = new int[]11,2,13,4,51;
    


题目二:输出是什么

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

    public static void func2(int[] array)
        array[0] = 99;
    

题解:

public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        int[] array = 1,2,3,4,5;
        int[] array2 = array;
     这代表  array2 这个引用 指向 引用array指向 的对象
     array 和 array2 指向的是同一个对象
    


⛵四、数组练习

1.模拟实现toString

题目要求:

public static String my_toString(int[] arr) 

        String s="[";

        for(int i=0;i<arr.length;i++)
        
            s=s+arr[i];
            if(i<arr.length-1)
                s+=",";
        
        s+="]";
        return s;
    
    public static void main(String[] args) 
        int[] arr = 1, 2, 3, 4, 5, 6;

        String ss=my_toString(arr);

        System.out.println(ss);

    

2.数组拷贝

数组的拷贝方式

  //数组拷贝
    public static void main(String[] args) 
        int[] arr = 1,2,3,4,5;
        int[] copy = new int[arr.length];
        for (int i = 0; i <arr.length ; i++) 
            copy[i] = arr[i];
        
        System.out.println(Arrays.toString(copy));
    

在这种拷贝方式中,我们首先通过 new 一个新的和 arr 一样长度数组 copy,再通过 for 循环将 arr 数组中的内容 一 一赋给copy数组,达到 最终的数组拷贝的效果.


(1)copyOf()

我们先通过JKD的工具文档,来看一下拷贝工具的用法

功能:复制指定的数组,用零截取或填充(如有必要),以便复制具有指定的长度.

具体看一下Java当中copyOf方法的具体实现

首先 Arrays.copyOf() 的返回类型是 int [ ] ,第一个参数是 原数组(要拷贝的数组),第二个参数是新数组的长度(可以自己定),如果新的数组的长度比原数组长的话,大于原数组长度的元素都补为0 。 具体如下所示…


(2)copyOfRange()

我们先通过JDK文档来查看这个工具类的功能

功能:将指定数组的指定范围复制到新的数组中.

具体看一下Java当中copyof方法的具体实现

 copyOfRange 方法的返回类型是 int [ ] ,第一个参数是 原数组 ,第二、三参数是要拷贝原数组数据的下标 ,一定要切记 是左闭右开的区间 , [ from , to ).

代码示例

我们打开 System.arraycopy 方法的具体实现,发现没有和上面几种拷贝方法的实现过程,System.arraycopy 有前面的 native 可知,这是一个本地方法。


本地方法

System.arraycopy 没有返回值,第一个参数原数组(要拷贝的数组),第二个参数是原始数组要拷贝的下标,第三个参数是目的地数组 ,第四个参数是 目的地数组的下标,第五个数组是要拷贝的长度.

代码示例:

注意点:

  System.arraycopy 最后一个参数 ——要拷贝的数组长度,这个数据不能超过原数组的长度,否则编辑器会发生错误报告:数组越界。


clone可以理解为是一份资料的备份

代码示例:


⌚五、理解深拷贝与浅拷贝

浅拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针,不复制堆内存中的对象。

深拷贝:复制基本类型的属性;引用类型的属性复制,复制栈中的变量 和 变量指向堆内存中的对象的指针和堆内存中的对象。


假设B复制了A,修改A的时候,看B是否发生变化:

如果B跟着也变了,说明是浅拷贝,拿人手短!(修改堆内存中的同一个值)

如果B没有改变,说明是深拷贝,自食其力!(修改堆内存中的不同的值)

通俗来说就是:


⚽六、二维数组

1.二维数组的创建

跟一维数组几乎一样,只要初始化了数据,你的[][]里就不能有数字的存在

public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        // 创建一个 2行3列的二维数组
        int[][] array = 1,2,3,4,5,6;
        int[][] array2 = new int[][]1,2,3,4,5,6;
        int[][] array3 = new int[2][3];
    

2.二维数组的打印

方法一:

public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        // 创建一个 2行3列的二维数组
        int[][] array = 1,2,3,4,5,6;
        int[][] array2 = new int[][]1,2,3,4,5,6;
        int[][] array3 = new int[2][3];
        print(array);
    
    public static void print(int[][] array)
        // 按照我们以前对C的理解,二维数组的存储模式应该为 图60
        for (int i = 0; i < 2; i++) 
            for (int j = 0; j < 3; j++) 
                //打印一行数据
                System.out.print(array[i][j] + " ");
            
            System.out.println();// 换行
        
    

如果计算的算,每个二维数组都自己去算它有几个元素吧。
怎么去获得 行 和 列?
这里就引用C语言的一个概念,二维数组是一个特殊的一维数组
经过前面讲解,大家都知道数组是存储在堆上的,再加上面这句话的概念

修改代码如下:

public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        // 创建一个 2行3列的二维数组
        int[][] array = 1,2,3,4,5,6;
        int[][] array2 = new int[][]1,2,3,4,5,6;
        int[][] array3 = new int[2][3];
        print(array);
        // 这里我们在用实例证明一下
        // array.length 是否能的得到 行数 2
        System.out.println(array.length);
        // array[下标].length 是否能得到 列数3
        System.out.println(array[0].length);
        System.out.println(array[1].length);
    
    public static void print(int[][] array)
        // 按照我们以前对C的理解,二维数组的存储模式应该为图60
        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();// 换行
        
    

方法二:

public class TheDefinitionAndUseOfArrays 
    public static void main(String[] args) 
        int[][] array = 1,2,3,4,5,6;
        print(array);
    
    public static void print(int[][] array)
        for (int[] ret:array) // array元素的数据类型是一个一维数组,我就需要一个相同的类型的变量来接收
            for (int x:ret) 
                // ret是一个一维数组的数组名,接下来就跟前面使用foreach是一样,将 引用ret 所指向的对象(数组)的元素,
                // 读取并赋值给 与其元素类型相同的变量, 我们再将其输出。就可以了
                System.out.print(x + " " );
            
            System.out.println();//换行
        
    


方法三:二维数组也有对应的 方法:Arrays.deepToString( 数组名 )

import java.util.Arrays;

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


⌛七、不规则的二维数组

(1)不规则二维数组定义

Java中不规则二维数组的定义


C语言中数组的定义

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

而在Java中我们只能 定义行,列不用规定值

int[][] arr = new int[2][];

代码如下:

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

编译结果:

首先我们规定了一个 有两行的二维数组

int [ ] [ ] arr = new int [2] [ ];

我们自己给每一行的数组规定有多少列。

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

这就是不规则的二维数组的定义。


(2)内存中的不规则二维数组

与规则的二维数组内存存储基本相同。


以上是关于JAVA SE—— 数组(详细!!!)的主要内容,如果未能解决你的问题,请参考以下文章

69期-Java SE-004_循环数组-001-002

Java SE之基础篇——方法

Java--SE简答题4

vbscript 各种自定义代码片段 - 有关详细信息,请参阅注释

java中LinkedList ArrayList 数组 HashSet 存储数据测试

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