6. 数组

数组的定义与使用

数组的创建及初始化

我们知道创建一个变量的步骤:

类型 变量名=初始值;

我们数组类似(java版):元素类型[]  数组名

但这和我们C语言会有所不同

例如:(C语言版)

数组(对象)的创建

元素类型[] 数组名=new 元素类型[数组长度];

如:

这里的array1、array2、array3都叫做引用变量  简称:引用

这里的new 是用来创建新的对象的  什么是对象(我们后面讲解 目前只需要记住这种形式)

数组的初始化

1.动态初始化:在创建数组时 直接指定数组中元素的个数

这种定义方式并没有初始化数组元素的值(会默认数组元素的值)

int赋初值为0  double赋初值为0.0  String赋初值为null

2.静态初始化:在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定

如:

注意事项

1.只能在定义数组的时候 对数组进行整体的初始化(不可先定义 再初始)

2.静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度

3.静态初始化时, {}中数据类型必须与[]前数据类型一致

4.静态初始化可以简写,省去后面的new 类型[]

如:

注意:虽然省去了new类型[], 但是编译器编译代码时还是会还原

数组也可以按照如下C语言方式创建,但不推荐

静态和动态初始化也可以分为两步,但是省略格式不可以(new 类型[]不可以省略)

如果没有对数组进行初始化,数组中元素有其默认值

如果数组中存储元素类型为基类类型,默认值为基类类型对应的默认值,比如:

如果数组中存储元素类型为引用类型,默认值为null

数组的使用

数组中元素访问

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

注意事项

1. 数组是一段连续的内存空间,因此支持随机访问,即通过下标快速访问数组中任意位置的元素

2. 下标从0开始,介于[0, N)之间不包含NN为元素个数,不能越界,否则会报出下标越界异常

如:

该数组大小为5 下标从0~4 这里访问下标为5处的值 会报出下标越界异常问题

遍历数组元素

通过循环的形式去遍历数组中每个元素

在java中 便有for和for each循环

1.for循环:在java代码中 我们不用去计算数组长度 可以用 数组名.length 来得到数组大小

array[i]+“ ”:我们已知道在java中 ‘+’代表拼接的作用 即:在每个元素后面拼接一个空格

2.for each循环

for(int x:array)

第一个参数的类型与数组元素类型相同 第二个参数是数组名

这里意思是:遍历数组array 取出每个元素放到x里面

在for each循环中 我们是无法获取 对应元素的下标的

for循环和for each循环其实输出是一样的 还有别的方法来输出数组元素

3.以字符串的形式 输出数组元素

使用Arrays的toString方法 把传入的参数array(数组) 以字符串的形式进行输出

数组是引用类型

初始JVM的内存分布

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

1. 程序运行时代码需要加载到内存

2. 程序运行产生的中间数据要存放在内存

3. 程序中的常量也要保存

4. 有些数据可能需要长时间存储,而有些数据当方法运行结束后就要被销毁

JVM对所使用的内存按照功能的不同进行了划分:

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

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

3.本地方法栈:本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局

部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的

4.方法区:用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数

据. 方法编译出的的字节码就是保存在这个区域  

为什么会有两个栈呢?(更简单的理解)

本地方法栈:会执行一些底层是由C/C++代码 实现的方法

Java虚拟机栈:就是我们平时嘴中说的栈

现在我们只简单关心 堆和Java虚拟机栈(简称栈)这两块空间  之后还会更详细介绍JVM

基本类型变量和引用类型变量的区别

基本数据类型创建的变量 成为基本变量 该变量空间中直接存放的是其所对应的值

而引用数据类型创建的变量 一般称为对象的引用 其空间中存储的是对象所在空间的地址

那到底什么是引用类型?

引用类型是对 对象(存储在堆中)的引用内存地址--数组首地址),而不是对象本身

当引用类型的变量被声明时 它们在栈中分配了空间 但此时这个空间并不存储实际的对象 而是存储了对象的引用(地址)

Java有三种主要的引用类型:

1.数组:数组也是引用类型 当你创建一个数组时(无论是基本数据类型的数据还是引用类型的数组) 实际上是在堆上为数组对象分配了空间 并在栈上为引用变量分配了空间 该引用变量指向堆上的数组对象

这里我们把输出的“地址”简写成0x9 如下图:

这里便是:在堆上为数组对象分配了空间 并在栈上为引用变量array分配了空间 该引用变量array指向堆上的数组对象

在之前我们使用过array.length和 array[0]

array.length:通过引用变量array 访问当前对象的长度

array[0]:通过引用变量array 访问当前对象下标为0处的内容

2. 类:这是最常见的引用类型。当你使用new关键字创建一个类的实例时 你实际上是在堆内存中为这个对象分配了空间 并在栈上为引用变量分配了空间 该引用变量指向堆上的对象

3.接口:接口也是一种引用类型。但是,你不能直接实例化一个接口(即使用new关键字)。相反,你必须实例化一个实现了该接口的类,并将结果引用赋值给接口类型的变量。

这里我们其实只要知道数组是引用类型即可 另外两种后面学习了之后 便会知道

记住一句话即可:在Java中 除了基本数据类型外 其他所有的类型(包括数组、类、接口)都是引用类型

再谈引用变量

我们从实例代码来讲解,代码如下:

这里 我们都将以图的形式 来讲解

在本题中 array1改变了其所指向的对象 而原先堆上地址为0x9的对象由于没人引用 会被JVM自动回收

总结:当两个引用同时指向一个对象时 通过任何一个引用都能修改这个对象的值

关于null

在java中 null表示“空引用”---》不指向对象的引用

null的作用类似于C语言中的NULL(空指针) 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作. 一旦尝试读写, 就会抛出 NullPointerException

注意: Java 中并没有约定 null 和 0 号地址的内存有任何关联.

总结:虽然Java没有直接的指针概念,但null在处理对象引用时仍然扮演着与指针语言中的空指针相似的角色。它是检查对象引用是否有效的常用方法,也是避免空指针异常的关键。

练习:(加深理解——非常重要)

我们接下来用几个例题来加深对数组的理解

  1. 让数组内的元素大小变成原先的两倍

方法1.新开一个数组 让该数组的元素=原先数组元素*2

其实 我们看到这个问题会觉得超级简单 但我们的目的不仅是会写这么简单的题目 而是深入去理解数组

  1. 数组作为函数的返回值
  2. 数组作函数的参数---》函数参数传数组类型(引用类型)

接下来我们仍然以图的形式加深大家的理解

当然我们还有另一个方法

方法2:在原先数组上 进行元素值*2

在上面我们将数组(传引用)作为函数的参数 然后完成目标操作

那是不是传引用就能够 修改实参的值?

当然不是的啦

例如:

总结:

  1. int[] array=null; 代表这个引用array 不指向任何对象
  2. array1=array2; 代表array1这个引用 指向了array2这个引用 指向的对象
  3. 一个引用不可能同时指向两个对象
  4. 所谓的 "引用" 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实 只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大).

二维数组

二维数组本质上也就是一维数组 只不过每个元素又是一个一维数组

基本语法:

数据类型[][] 数组名称=new 数据类型[行数][列数]{初始化数据};

以下代码都是可行的:

我们同样以图的形式给大家展示:

不规则二维数组

创建一个一维数组 其元素是整型数组(代表行)

然后初始化每行 每行可以有不同的长度

array是一个引用数组 它包含两个引用 每个引用指向一个不同长度的整型数组

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值