【JavaSE篇】——数组的定义与使用

目录

本章的目标: 

🎈数组的基本概念

🍭创建数组

🍭数组的初始化

🍭数组的使用

👉数组中元素访问

👉遍历数组

🎈数组是引用类型

🍭初始JVM的内存分布

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

👉基本数据类型变量

👉引用数据类型变量

🚩再谈引用变量

🍭认识null

🎈数组的应用场景

🍭保存数据

🍭作为函数的参数

🍭作为函数的返回值

🎈二维数组

🍭创建二维数组

🍭数组转为字符串

🍭二维数组的解析

🍭遍历

🎓不规则的二维数组


本章的目标: 


🎈数组的基本概念

什么是数组 :可以看成是 相同类型元素的一个集合 。在内存中是一段连续的空间。 java 中,包含n个整形类型元素的数组。
  • 1. 数组中存放的元素其类型相同
  • 2. 数组的空间是连在一起
  • 3. 每个空间有自己的编号,其实位置的编号为0,即数组的下标

🍭创建数组

T[] 数组名 = new T[N];T:表示数组中存放元素的类型
T[]:表示数组的类型
N:表示数组的长度
 public static void main(String[] args) {int[] array1=new int[5];  //创建一个可以容纳5个int类型元素的数组double[] array2=new double[5];// 创建一个可以容纳5个double类型元素的数组float[] array3=new float[5];// 创建一个可以容纳5个float类型元素的数组}

我们可以对比c语言的创建数组,int arr[N]={0,1,2};

java创建数组是 int[] arr=new int[N];

其实我们更可以看到java 更能理解,因为arr是数组名,它是Int[]类型是数组arr的类型,而c语言中arr是数组名,int是数组里面的值的类型,并不是数组的类型,数组的类型是int[]。

该种定义方式不太友好,容易造成数组的类型就是 int 的误解
[] 如果在类型之后,就表示数组类型,因此 int[] 结合在一块写意思更清晰。

🍭数组的初始化

数组的初始化主要分为 动态初始化以及静态初始化

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

语法格式: T[] 数组名称 = {data1, data2, data3, ..., datan};

int[] array1 = new int[]{0,1,2,3,4,5,6,7,8,9};//静态
double[] array2 = new double[]{1.0, 2.0, 3.0, 4.0, 5.0};//静态
String[] array3 = new String[]{"hell", "Java", "!!!"};//静态
动态初始化:在创建数组时,直接指定数组中元素的个数
int [] array = new int [ 10 ];
int[] array1 = new int[10];//动态
double[] array2 = new double[10];//动态
String[] array3 = new String[10];//动态


【注意事项】
  • 静态初始化虽然没有指定数组的长度,编译器在编译时会根据{}中元素个数来确定数组的长度。
  • 注意:在数组中可以通过 数组对象.length 来获取数组的长度

  • 静态初始化时, {}中数据类型必须与[]前数据类型一致。
  • 静态初始化可以简写,省去后面的new T[]。

int[] array={1,2,3,4};//静态初始化可以省略new T[];

  • 静态和动态初始化也可以分为两步,但是省略格式不可以
int[] array;
array=new int[10];//静态初始化的拆分
int[] array1;
array1=new int[]{1,2,3,4};//动态初始化的拆分

这里就不能省略new.

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

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

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

在一般实际的做题目中,我们用到的最多的是int[] arr=new int[N],因为这样会给默认值,然后开辟了N个长度的数组,然后我们依次赋值。


🍭数组的使用

👉数组中元素访问

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

【注意事项】
1.数组是一段连续的内存空间,因此 支持随机访问,即通过下标访问快速访问数组中任意位置的元素
2. 下标从 0 开始,介于 [0, N )之间不包含 N N 为元素个数,不能越界,否则会报出下标越界异常。

所以访问数组的下标不能到array[array.length],不能取到长度。


👉遍历数组

所谓 "遍历" 是指将数组中的所有元素都访问一遍, 访问是指对数组中的元素进行某种操作,比如:打印。

  • for-i遍历数组

  • 使用 for-each 遍历数组

俩者的不同之处是

  • for-i 可以访问到下标,如果对数组中的第二位置的值+1,那么就可以用for-i,则不可以使用for-each。
  • for-each不可以访问到下标,不需要取到特定的值即可用。
  • 借用Java本身提供的一些方法来实现数组的打印

这里首先需要介绍一个 工具类(可以理解为C语言里面的头文件):Arrays

       其主要作用是:帮助对数组进行一个操作(详情可查找帮助手册)

我们可以再成长手册或者这里可以看到有很多类型的数组,这里就表示重载,后面我会详细说。现在可以理解为哪种数组类型就调用哪个哪个。这里是int类型那么我们就toString(int[] a).

这里用数组转换成字符串形式,我们可以看到加了[],为啥会加[]我们可以再toString中ctrl+鼠标左键,进入源码中查看

现在我们并不能完整的看懂这段底层实现的代码,我们可以根据现象直接实现,[1,2,3]这种形式,我们自己实现一下。

   public static void myString(int[] array){System.out.print("[");for(int i=0;i<array.length;i++){if(i!=array.length-1) {System.out.print(array[i]+",");}else System.out.print(array[i]);}System.out.print("]");}public static void main(String[] args) {int[] array={1,2,3,4};myString(array);}

🎈数组是引用类型

🍭初始JVM的内存分布

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

  • 虚拟机栈(JVM Stack): 与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含 有:局部变量表操作数栈动态链接返回地址以及其他的一些信息,保存的都是与方法执行时相关的一 些信息。比如:局部变量。当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了
  • (Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} )堆是随着程序开始运行时而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销

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

  • 基本数据类型创建的变量,称为基本变量,该变量空间中直接存放的是其所对应的值;
  • 引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址

👉基本数据类型变量


👉引用数据类型变量

我们大标题是数组是引用数据类型 ,我们就根据数据来阐述。

我们可以通过ox77的地址找到对象。这里的array是变量(引用变量,存储的是对象的地址),引用(指向)一个数组对象。这个数组对象在堆区,我们需要存储这个对象的地址,所以array这个变量存储了,叫做引用变量。

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


🚩再谈引用变量

我们现在给引用变量修改值或者一个数组给另一个数组是如何运行的。

场景1

这个底层是如何实现的呢?

array引用变量存储的是数组对象的首元素的地址,都初始化成默认值0,然后我们对下标为0和下标为1的位置对应的值进行改变,还是对堆上的空间进行改变,array并没有新开一个空间。所以最终array前后打印的值是不一样的。


场景2


这个场景可能有些迷了,array1和array2该输出什么呢?我们一步一步的分析。

场景3

由于array1的空间给了array2,那么对array1的改变,array2也改变了。


场景四

🍭认识null

null 在 Java 中表示 "空引用" , 即:一个不指向对象的引用。

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

🎈数组的应用场景

🍭保存数据

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

🍭作为函数的参数

我们调用func1,首先a引用变量存放ox13的地址,再调用这个函数是arr也指向a的空间,然后arr开辟一个空间,地址是0x99,然后arr指向了地址为0x99的空间,但是a指向的空间并没有改变。所以打印的结果还是1,2,3,4。


调用func2呢?

a引用变量存的是0x13的地址,指向了一块空间,调用func2,也指向了这块空间,然后arr对0位置进行改变,就是相当于对这片空间的下标为0的位置改变。

发现在 func 方法内部修改数组的内容 , 方法外部的数组内容也发生改变 .
因为数组是引用类型,按照引用类型来进行传递,是可以修改其中存放的内容的。
上面俩种调用
  •    第一种修改了自己的指向(因为自己开了一块空间),自己是形参,所以对自己的修改并不会影响实参的修改。
  •    第二种修改指向的对象里的值,所以改变指向的对象里面的值,就会改变实参的值

这下面很明显是修改指向的对象里的值,自己没有开空间,所以改变了实参的值。


总结: 所谓的 "引用" 本质上只是存了一个地址. Java 将数组设定成引用类型, 这样的话后续进行数组参数传参, 其实 只是将数组的地址传入到函数形参中. 这样可以避免对整个数组的拷贝(数组可能比较长, 那么拷贝开销就会很大).

🍭作为函数的返回值


🎈二维数组

🍭创建二维数组

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

java中默认值依旧是0;


🍭数组转为字符串

依旧是Arrays类里的方法


🍭二维数组的解析

二维数组本质上也就是一维数组, 只不过每个元素又是一个一维数组.
相当于俩行三列的数组。
arr[0]实际是第一行的数组,arr[1]是第二行的数组,数组名[0]其实是数组首元素的地址。

🍭遍历

for-i


for-each

 for (int[] array:arr1) {for(int x:array){System.out.print(x+" ");}System.out.println();}


🎓不规则的二维数组

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

没有列的不规则的二维数组。

它的好处是可以随机设置每一行的长度。


今天很讨厌张老师

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/434620.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2024017期传足14场胜负前瞻

2024017期赛事由亚洲杯2场、英总杯2场、德甲2场、意甲4场、西甲4场组成。售止时间为1月28日&#xff08;周日&#xff09;19点00分&#xff0c;敬请留意&#xff1a; 本期深盘场次同样适中&#xff0c;1.5以下赔率3场&#xff0c;1.5-2.0赔率6场&#xff0c;其他场次基本皆是平…

Java复习系列之阶段二:数据库

1. 基础语法 1.1 DQL&#xff08;数据查询语句&#xff09; 执行顺序&#xff1a; from、join 、on、where、group by、having、select、distinct、order by、limit 1.2 DML&#xff08;数据修改语言&#xff09; 对数据表的增删改 insert into update set delete form 1.…

javax.servlet.http包

javax.servlet.http包 javax.srvlet.http包是对javax.servlet包的扩展。该包的类和接口处理使用HTTP进行通信的servlet。这些servlet也称为HTTP Servlet。您需要扩展HttpServlet类来开发HTTP Servlet。javax.servlet.http包经常使用的接口包括: HttpServletRequest接口HttpSe…

Java 基础 - 反射

Java 基础 - 反射 文章目录 Java 基础 - 反射1 什么是类对象2 获取类对象的方法3 反射通用操作【重点】3.1 常见方法3.2 通用操作 4 内省 1 什么是类对象 类的对象&#xff1a;基于某个类 new 出来的对象&#xff0c;也称为实例对象。 类对象&#xff1a;类加载的产物&#x…

第9章 多线程

第9章 多线程 学习目标 了解进程和线程的区别 能够理解并发与并行的区别 能够使用继承类的方式创建多线程 能够使用实现接口的方式创建多线程 能够说出实现接口方式的好处 能够解释安全问题的出现的原因 能够使用同步代码块解决线程安全问题 能够使用同步方法解决线程安全问题…

滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编

滴水逆向三期笔记与作业——02C语言——10 Switch语句反汇编 一、Switch语句1、switch语句 是if语句的简写2、break加与不加有什么特点?default语句可以省略吗&#xff1f;3、游戏中的switch语句&#xff08;示例&#xff09;4、添加case后面的值&#xff0c;一个一个增加&…

Java笔记 --- 二、Stream流

二、Stream流 结合Lambda表达式&#xff0c;简化集合、数组的操作 获取Stream流对象 单列集合获取Stream流 双列集合获取Stream流 数组获取Stream流 一堆零散的数据获取Stream流 Stream流的静态方法of的形参是一个可变参数&#xff0c;可以传递零散数据&#xff0c;也可以传递…

记录一道ctf web题

0x00 前言 某同学发在群里一道不知道什么ctf的web题 0x01 bypass open_basedir 开始没想那么多&#xff0c;看到了可以执行phpinfo&#xff0c;直接先eval一个一句话上去看看什么情况&#xff1a; 接着发现了没有权限去读取/var/www/html以外的目录&#xff0c;那么我开始想的…

基于51单片机智能电子秤

实物显示效果&#xff1a; https://www.bilibili.com/video/BV1Wb4y1A7Aw/?vd_source6ff7cd03af95cd504b60511ef9373a1d 功能介绍&#xff1a; &#xff08;1&#xff09;用键盘设计单价&#xff1b; &#xff08;2&#xff09;称重后同时显示该物品的重量、单价和总额&…

sqlx的初体验

sqlx的介绍和优点 sqlx 是一个用于 Go 语言的数据库工具&#xff0c;它在标准库的 database/sql 包的基础上提供了一些额外的功能&#xff0c;使得数据库操作更加方便和灵活。 优点&#xff1a; 查询构建器&#xff1a; sqlx 提供了更强大的查询构建器&#xff0c;使得在 Go…

Ubuntu添加AppImage到桌面及应用程序菜单

将AppImage添加到桌面&#xff0c;以PicGo为例 效果&#xff1a; 在桌面创建PicGo.desktop文件&#xff0c;输入以下内容&#xff1a; [Desktop Entry] EncodingUTF-8 TypeApplication #应用名称 NamePicGo #图标路径 Icon/usr/local/AppImage/icons/PicGo.png #启动是否开启…

通俗易懂理解FCN全卷积网络模型

温故而知新&#xff0c;可以为师矣&#xff01; 一、参考资料 深度学习笔记&#xff08;二十三&#xff09;Semantic Segmentation(FCN/U-Net/PSPNet/SegNet/U-Net/ICNet/DFANet/Fast-SCNN) 二、FCN相关介绍 1. FCN简介 全卷积神经网络(Fully Convolutional Networks, 简称…