零基础 “入坑” Java--- 六、数组(一)

一、初识数组

在学习变量的时候,我们知道如何定义一个变量;现在有一个要求,需要定义100个整型变量,以我们现在所学的知识,我们只能逐个定义,但这无疑是个耗时耗力的方法,为了解决类似的问题,我们引入数组的概念。

数组是 相同数据类型元素的集合,在内存中是一段连续的存储空间。

对于数组我们需要了解:

1.数组中存放的元素应为同种数据类型。
2.数组的存放空间是连续的。
3.每个存放空间都有自己的编号,即数组下标,起始位置编号为0。

二、数组的创建与初始化

1.数组的创建

语法格式:

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


T:表示数组中存放元素的数据类型
T[]:表示数组的类型
N:表示数组的长度

如:

        //创建一个数组,可以容纳10个int类型的元素
        int[] array = new int[10]; 

2.数组的初始化

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

2.1 动态初始化

在创建数组时,直接指定数组中元素的个数:

int[] array = new int[10];

2.2 静态初始化

在创建数组时不直接指定数组中元素个数,而直接指定具体的元素内容:
语法格式:

T[] 数组名 = new int[]{元素1,元素2,…};

如:

int[] array1 = new int[]{1,2,3,4,5};

注意事项:
1.静态初始化时虽然没有指定数组长度,但是编译器会根据{}中的元素个数来确定。
2.静态初始化时,{}中的数据类型必须与[]前的数据类型保持一致。
3.静态初始化可以简写,省掉new T[]。如:

int[] array2 = {1,2,3,4,5};

静态初始化和动态初始化均可以分为两条语句书写,但当静态初始化分为两条语句时,不可简写:

        //动态初始化
        int[] array;
        array = new int[10];
        //静态初始化
        int[] array1;
        array1 = new int[]{1,2,3,4,5};
        
        //静态初始化错误写法 ×
        int[] array2;
        array2 = {1,2,3,4,5};

如果没有对数组进行初始化,则数组中的元素存在默认值:
当元素为基本数据类型时,默认值为:
在这里插入图片描述
当元素为引用类型时,默认值为null。

三、数组的使用

1.访问数组中的元素

数组在内存中是存放在一段连续的空间中,这段空间的编号从0开始依次递增,此编号称为下标,数组可以通过下标访问数组中任意位置的元素:

        int[] array = new int[]{1,2,3,4,5};
        System.out.println(array[0]); //1
        System.out.println(array[1]); //2
        System.out.println(array[2]); //3
        System.out.println(array[3]); //4
        System.out.println(array[4]); //5

        //可以通过下标对数组中的元素进行修改
        array[0] = 100;
        System.out.println(array[0]); //100

注意:
1.因为数组是一段连续的存储空间,所以支持随机访问,即通过下标快速访问数组中任意位置的元素。
2.下标从0开始,到N - 1结束(N为元素个数),在使用下标时,需注意不能越界,否则会导致程序报错:

        int[] array = new int[]{1,2,3,4,5};
        System.out.println(array[5]); 

运行结果为:
在这里插入图片描述

2.遍历数组

遍历是指将数组中的所有元素都访问一遍,我们可以使用下标来逐个访问,如:

        int[] array = new int[]{1,2,3,4,5};
        System.out.println(array[0]); //1
        System.out.println(array[1]); //2
        System.out.println(array[2]); //3
        System.out.println(array[3]); //4
        System.out.println(array[4]); //5

但当数组中元素个数较多时,这种办法就不太适合了,我们可以使用循环来完成此操作:

        int[] array = new int[]{1,2,3,4,5};
        for (int i = 0; i < 5; i++) {
            System.out.println(array[i]);
        }

当数组中元素个数较少,我们可以使用肉眼观察,但当元素个数较多时,我们该怎么办呢?

在数组中,可以通过 数组名.length 获取数组长度。 我们将上面的代码以这种形式改写:

        int[] array = new int[]{1,2,3,4,5};
        for (int i = 0; i < array.length; i++) {
            System.out.println(array[i]);
        }

Java也给我们提供了一种更简单的循环方式:for-each 用来遍历数组:

        int[] array = new int[]{1,2,3,4,5};
        for (int i:array) {
            System.out.println(i);
        }

使用 for-i 循环和 for-each 循环最主要的区别在于能否通过下标进行操作。

四、数组是引用类型

        int[] array = new int[]{1,2,3,4,5};
        System.out.println(array); //[I@1b6d3586

对于上面这段代码,我们可以将其运行结果的值理解为在内存上的"地址",引用变量就是用来存储"地址"的变量。

五、Java虚拟机(JVM)的内存分布

内存是一段连续的存储空间,主要用来存储程序运行时的数据。

JVM按照不同的功能对使用的内存进行了分类:
在这里插入图片描述
在本章节中,我们主要使用虚拟机栈和堆:
虚拟机栈: 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含有:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的一些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了。
: JVM所管理的最大内存区域。使用 new 创建的对象都是在堆上保存(例如前面的 new int[]{1,2,3,4,5} ),堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁。

六、基本类型变量和引用类型变量

基本数据类型创建的变量,称为基本变量,变量空间中存放的是其所对应的值;而引用数据类型创建的变量,称为对象的引用,在其空间中存放的是对象所在空间的地址。

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

在这里插入图片描述
通过上图分析可知,引用变量并不是直接存储对象本身,而是存储对象在堆中的起始地址,通过地址即可对对象进行操作。

理解了上面这些,我们再来看一个例子:

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

在这里插入图片描述
通过上面这个例子,我们引申出一些知识点:

1.当方法执行完毕时,方法内的局部变量会被回收。
2.当对象没有人引用(指向)时,也会被自动回收。
3.对象一定是在堆上的,但引用变量不一定在栈上。
4.当两个引用同时指向一个对象时,不管通过哪个引用,都可以修改数组对象的值。

七、空引用

在Java中,null表示空引用,意为不指向任何对象的引用,表示一个无效的内存位置。因此,不能对这块内存进行任何读写操作,这会导致程序抛出异常:

        int[] array = null; //array不指向任何对象
        System.out.println(array[0]);

运行结果为:
在这里插入图片描述

八、数组的使用

1.作为函数的参数

我们来分析一段代码:

    public static void func1(int[] array){
        array = new int[10];
    }
    public static void func2(int[] array){
        array[0] = 99;
    }
    public static void main(String[] args) {
        int[] array = {1,2,3,4};
        func1(array);
        for (int i = 0; i < array.length ; i++) {
            System.out.print(array[i] + " ");
        }
        System.out.println();

        int[] array1 = {1,2,3,4};
        func2(array1);
        for (int i = 0; i < array1.length; i++) {
            System.out.print(array1[i] + " ");
        }
	}

在这里插入图片描述
在这里插入图片描述
引用本质上就是存储的地址。 在上面的这段代码中,func1和func2都是将引用作为参数进行传递,func1改变了指向,所以没有对原数组产生影响,func2通过下标改变了对象的值,所以原数组也发生改变。

2.作为函数的返回值

在Java中,数组可以作为返回值返回一组数据:

    public static int[] func(){
        int[] array = {1,2,3,4,5};
        return array;
    }
    public static void main(String[] args) {
        int[] ret = func();
        for (int i = 0; i < ret.length; i++) {
            System.out.print(ret[i] + " ");
        }
    }

未完待续…

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值