数组的定义与使用

本文详细介绍了Java中的数组,包括定义、初始化、使用及数组长度的获取。此外,讲解了基本类型变量与引用类型变量的区别,并探讨了数组拷贝的四种方法。还提供了模拟实现`Arrays.toString()`、计算数组平均值以及数组元素查找的示例代码。最后,讨论了二维数组的初始化和打印,以及不规则数组的概念。
摘要由CSDN通过智能技术生成

1. 数组的基本概念

定义:数组是一块连续的存储空间,存储的是相同类型的元素。

T[] 数组名 = new T[N];

 切记:数组不能越界。


1.1 求数组长度

不需要像c中的sizeof()函数,Java中求数组长度直接用:数组名.length


1.2 数组的三种初始化方法

int[] arr1={1,2,3,4};//直接赋值 静态初始化
int[] arr2=new int[]{1,2,3,4};//动态初始化
int[] arr3=new int[10];//只是分配了内存 但是没有进行赋值 只有默认值 且其中的10个都是0

如果只是分配了内存,则其默认存储值如下:


1.3 数组的使用

Java中引用了专门用于数组的打印形式:

找到其中的for each,点击会出现以下形式:

 :左边填数组当中数据类型定义的变量,:右边填数组名。

 这两种循环本质上没有任何区别。

另外,打印数组的另外一种方法:Arrays

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


2.1. 初始JVM的内存分布

程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址

虚拟机栈(JVM Stack): 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。

本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的

堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。

方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域

现在我们只简单关心堆 和 虚拟机栈这两块空间,后序JVM中还会更详细介绍。


2.2 基本类型变量与引用类型变量的区别

 

 从上图可以看到,引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。有点类似C语言中的指针,但是Java中引用要比指针的操作更简单。


2.3 再谈引用变量

 这段代码中的int[ ] arr2=arr1实际上等于把arr1的地址赋给了arr2所以使得一个地址同时指向两个数组,故更改arr2的值也会影响arr1的值,类似于c语言中的数组。

另外,Java中的数组是存放在堆上的,而变量赋值和方法创建都是在栈上进行的。

Java中的数组属于引用类型,主要是因为数组都是存放在堆上的,而栈中只是存放了数组的地址,属于引用了堆上的数组,所以叫引用类型。

另外,数组是引用类型无法用整形类型赋值,要想赋值需要用NULL进行赋值,代表这个引用不指向任何内容。

 

 fuc1相当于新建了一个数组并且修改了形参自己的指向,而fuc2相当于修改了指向的数组中存放的内容。

注意: 

 

 整体初始化只有一次机会,就是在定义的同时初始化。

结构体、数组都是聚合类型,凡是聚合类型都是整体初始化机会只有一次。


2.4 数组的拷贝

方法一:

直接使用Arrays.copyOf进行拷贝

另外,扩容拷贝数组只需要在长度上乘个二。

方法二:

利用System.arraycopy可以指定完成目标到目标的拷贝

按住ctrl+鼠标左键点开System.arraycopy方法,即可查看一下变量

根据目录填入数据,即可完成拷贝。

 另外,它也支持局部拷贝。

方法三:

利用Arrays.copyOfRange拷贝数组中的局部内容。

注意:Java中的范围都是[3,5)左闭右开的。

 方法四:

直接使用clone()方法进行克隆。

 alt+7打开代码索引。


 3 例题

1. 模拟实现Arrays.toString()函数

注意:1.要考虑null的情况。

           2.注意‘   [   ’   ,   '  ]   '    ,    '   ,   '

public static String My_toString(int[] tmp) {
        if (tmp == null) {
            return "null";
        }
        String ret = "[";
        for (int i = 0; i < tmp.length; i++) {
            ret += tmp[i];

            if (i != tmp.length - 1) {
                ret += ",";
            }
        }
        ret += "]";
        return ret;
    }

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

2. 求数组中元素的平均值

 public static double avg(int[] arr){
        int sum=0;
        for (int x:
             arr) {
            sum+=x;
        }
        return sum*1.0/arr.length;
    }
    public static void main(String[] args) {
        int[] arr={1,2,3,2,3,5,8,3};
        System.out.println(avg(arr));

    }

3. 查找数组中指定元素(顺序查找)

方法一:直接查找

public static int fuc(int[] arr,int num){
        for (int i = 0; i < arr.length; i++) {
            if(arr[i]==num){
                return i;
            }
        }
        return -1;
    }
    public static void main(String[] args) {
        int[] arr={1,2,8,55,66,45,25};
        Scanner scanner=new Scanner(System.in);
        int num=scanner.nextInt();
        System.out.println(fuc(arr, num));
    }

方法二:二分查找

知识点补充:数组从小到大快速排序方法:Arrays.sort()。

 注意:不是冒泡排序,底层是快排。

所以二分查找就完成了: 

 public static  int sort(int arr[],int num){
        int left=0;
        int right=arr.length-1;
        for (int i = 0; i < arr.length; i++) {
            int mid=(left+right)/2;
            if(arr[mid]<num){
                left=mid+1;
            }
            else if(arr[mid]>num){
                right=mid-1;
            }
            else{
                return mid;
            }
        }
        return -1;
    }
    public static void main(String[] args){
        int[] arr={2,5,6,4,33,64,85,25};
        Scanner scanner=new Scanner(System.in);
        int num=scanner.nextInt();
        System.out.println(sort(arr, num));

    }

方法三:二分查找(系统板)方便

 public static void main(String[] args) {
        int[] arr={2,5,6,4,33,64,85,25};
        System.out.println(Arrays.binarySearch(arr, 33));
    }

4. 额外补充:

1. 倒叙排序数组

public static void sort(int[] arr){
        int left=0;
        int right=arr.length-1;
        while(left<right) {
            int tmp=arr[left];
            arr[left]=arr[right];
            arr[right]=tmp;
            left++;
            right--;
        }
    }
    public static void main(String[] args) {
        int[] arr={2,5,6,4,33,64,85,25};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }

2. 数组比较使用Arrays.equals()方法

 3. 快速初始化数组:利用Arrays.fill()方法

 部分初始化数组:利用Arrays.fill()方法


5. 二维数组

5.1 二维数组的初始化

二维数组的三种初始化方式:

public static void main(String[] args) {
        int[][] arr1=new int[3][5];
        int[][] arr2=new int[][]{{1,2,3},{3,6,5}};
        int[][] arr3={{2,5,6},{8,5,6}};
    }

5.2 二维数组的打印 

方法一:如果把二位数组当成其列数个一维数组,则i的范围将是i<arr.length

而j的范围将是j<arr[i].length.

public static void main(String[] args) {
        int[][] arr = {{4, 5, 6}, {1, 2, 3}};
        paint(arr);
    }

    public static void paint(int[][] arr) {
        for (int i = 0; i < arr.length; i++) {
            for (int j = 0; j < arr[i].length; j++) {
                System.out.print(arr[i][j] + "  ");
            }
            System.out.println();
        }
    }

 方法二:因为二维数组的每个元素都是一维数组,所以可以这样打印。

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

 方法三:利用Arrays.deepToString进行打印

注意:这种打印方法无法换行。 


5.3 不规则数组

不规则数组就是只规定行,不规定列的数组。

其输出结果为null

 不规则数组的优点是:可以自定义二维数组中一维数组的大小。

 其原理是如下图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值