Java---数组的定义和使用和JVM的内存情况

数组

我们为什么会用到数组呢?Java中为啥会定义数组呢?在Java中变量的定义是数据类型 变量名 = 初始值。那么我们要是定义10个整型的变量呢?定义100个整型的变量呢?我们一个一个定义岂不是很麻烦而且很慢?所以引出了数组。

数组的定义

数组是用来盛放同种数据类型的集合,在内存中是一个连续的空间。

数组的创建

数组的创建
方式一:
数据类型 [] 数组名 = new 数据类型[N](和前面的一致);
N是用来存放数组长度的
方式二:
数据类型 数组名[] = {元素};//这种不建议使用,和C语言中的一样。int []这样定义更清晰

数组的初始化

数组的初始化分为动态初始化和静态初始化。

//静态初始化
    int [] arr = new int[] {1,2,3};
    但我们编写的时候一般省略new int[]
    int [] arr = {1,2,3};虽然省略了new int[]但是编译的时候,计算机会自己加上,这样只是方便了我们编写代码。
//动态初始化
    int [] array = new int[10];

这里我来说几个注意点:

  • 在上面的静态初始化时,可以不用在后面的new int[]中指定长度,因为计算机会根据{}中的元素来确定长度。
  • 静态初始化的时候,{}中的数据类型必须与前面的一致。
  • 对于静态初始化我们有两种方式,上面也提到过了,这里需要注意,完整写法的可以拆分写,简写方式的不可以。
int [] arr = new int[]{1,2,3,4};//这样的时候可以拆开来写
int [] arr;
arr = new int[]{1,2,3,4};
//简写的时候不可以拆开来写
int [] arr = {1,2,3,4};
int [] arr;
arr = {1,2,3,4};//这样拆开写会编译错误
  • 对于动态初始化时,后面标明了元素的个数:10。数组中下标是从0开始的,所以10个元素下标是0-9.
  • 对于没有初始化的数组,系统会自动分配默认值,动态分配时,创建了10个int类型的元素,但并没有赋值,此时系统会分配默认值0。下图为数组在内存中存储的情况和对于基本数据类型的默认值。
    对于引用类型的默认值是null。(null 在 Java 中表示 “空引用” , 也就是一个不指向对象的引用。Java中null并不是就是等于0)
    在这里插入图片描述
    在这里插入图片描述
  • 对于动态分配时也可以拆开编写。
int [] arr = new int[10];和下面拆开后一样。
int [] arr;
arr = new int [10];

数组的使用

数组最常用到的就是遍历和访问元素。

  1. 访问元素
    数组中的元素下标为[0,N),比方说有10个元素,下标能取到的就是0-9。由于数组在内存中的地址是连续的,所以访问具有随机性。通过数组名[下标]来访问。
  2. 遍历元素
    元素的遍历可以理解为三种方式,这里也需要知道一个知识点,对于数组的长度,我们可以使用数组名.length来求得。
        //遍历数组
        int [] arr = new int[] {1,2,3,4,5,6,7,8,9};
        for(int i = 0; i < 9; i++) {
            System.out.print(arr[i] + "\t");
        }
        for (int i = 0; i < arr.length; i++) {
            System.out.print(arr[i] + "\t");
        }
        for (int x:arr) {
            System.out.print(x + "\t");
        }

第一种的长度为我们自己数出来的,但如果元素很多,我们再一个一个数就很不现实,所以用到更多的为第二种方法,使用length求得数组的长度。
方法三为for-each方法遍历数组,这里用到的不是数组下标遍历,而是访问数组的元素,for(int x:arr),定义一个变量和数组元素同类型,然后去访问数组内的元素。

JVM内存分布

在最初,我就直接告诉你们了,对象存在堆上,局部变量存在栈上,那么其余的呢?内存到底怎么分布的呢?
在这里插入图片描述

再谈基础数据类型和引用类型

根据上述画的图我猜大家也对内存有了了解,而且对于基本数据类型和引用类型的区别也有了大致了解。
基本数据类型存储的为值
引用数据类型存储的为地址。
在这里插入图片描述

数组练习

在我上一篇文章中,也有数组的使用,也是个易考点,详细可以看看上一篇的那一块。数组的形参实参

java.util.Arrays这个包中包含了很多操作数组的方法,我们可以自己编写方法也可以使用Arrays自带的

数组的拷贝

        //数组拷贝
        //自己编写的拷贝
        int[] arr = {1,2,3,4};
        int[] array = arr;
        //Arrays中的拷贝
        int[] array1 = Arrays.copyOf(arr,arr.length);
        //范围拷贝
        int[] array2 = Arrays.copyOfRange(arr,2,3);//范围拷贝,[2,3)
        System.out.println(Arrays.toString(array));
        System.out.println(Arrays.toString(array1));
        System.out.println(Arrays.toString(array2));

自己编写的拷贝和Arrays中自带的拷贝有啥区别呢?来看图吧!
在这里插入图片描述

输出数组

上面我们也用到了,输出数组我们可以遍历输出,我们也可以用Arrays中的方法
Arrays.toString(数组名)-----将数组转为字符串输出

输出数组中元素平均值

        int[] array = {1,2,3,4};
        int sum = 0;
        double avg = 0;
        for (int x:array) {
            sum += x; 
        }
        avg = sum / (double)array.length;
        System.out.println(avg);

顺序查找指定元素

        //顺序查找指定元素
        int[] arr = {1,8,9,3,7,59,6};
        int count = 0;
        for(int x : arr) {
            if (x == 59) {
                System.out.println("下标是:" + count);
                System.out.println("找到了");
            }else {
                count++;
                continue;
            }
        }

二分查找

这个只可用于有序数组。

        //二分查找,只可以用于有序的数组
        int[] arr = {14,15,36,49,59,88};
        int num = 59;
        int mid = arr.length / 2;
        int left = 0;
        int right = arr.length - 1;
        while (left <= right) {
            if (arr[mid] == num) {
                System.out.println(mid);
                System.out.println("找到了");
                break;
            }else if (arr[mid] > num) {
                right = mid - 1;
                mid = (left + right) / 2;
            }else {
                left = mid + 1;
                mid = (left + right) / 2;
            }
        }

冒泡排序

我写的这个冒泡并不是最快的,还有很多优化方法,大家可以发在评论区。

        //冒泡排序
        int[] arr = {15,96,55,3,1,58};
        int temp = 0;
        //趟数
        for (int i = 0; i < arr.length - 1; i++) {
            //每趟比较的次数
            for (int j = 0; j < arr.length - 1; j++) {
                if (arr[j] < arr[j + 1]) {
                    continue;
                }else {
                    temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        System.out.println(Arrays.toString(arr));

数组逆序

        //数组逆序
        int[] arr = {12,59,86,1,58,33};
        int left = 0;
        int right = arr.length - 1;
        int temp = 0;
        while (left < right) {
            temp = arr[right];
            arr[right] = arr[left];
            arr[left] = temp;
            left++;
            right--;
        }
        System.out.println(Arrays.toString(arr));

二维数组

二维数组本质上也是一维数组。
二维数组的定义为

数据类型[][] 变量名 = new 数据类型[行数][列数]{初始化数据};
int[][] arr = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};也可以这样初始化

在这里插入图片描述
二维数组的行数和列数可以不同。列数可以省略,但是行数不可以省略。
三维思维数组同理,大家自己试着画画内存图吧!

  • 16
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值