JavaSE语法之五:数组的定义与使用(超详解!!!)

文章目录

    • 一、数组的概念
      • 1. 什么是数组
      • 2. 数组的创建及初始化
      • 3. 数组的使用
        • 3.1 数组中元素的访问
        • 3.2 遍历数组
    • 二、数组是引用类型
      • 1. 初始JVM的内存分布
      • 2. 基本类型变量与引用变量的区别
      • 3. 引用变量
      • 4. 认识null
    • 三、数组的应用场景
      • 1. 保存数据
      • 2. 作为函数的参数
        • 2.1 参数传基本类型
        • 2.2 参数传数组类型(引用数据类型)
      • 3. 作为函数的返回值
    • 四、二维数组

一、数组的概念

假设存5个学生的考试成绩,并进行输出,我们用之前掌握的知识点来写:

public class TestStudent{public static void main(String[] args){int score1 = 70;int score2 = 80;int score3 = 85;int score4 = 60;int score5 = 90;System.out.println(score1);System.out.println(score2);System.out.println(score3);System.out.println(score4);System.out.println(score5);}
}

假如存20个、100个同学的成绩呢?不仅非常麻烦,代码也非常冗余,我们仔细观察可以发现:所有成绩的类型都是相同的, 那就引出我们的数组。

1. 什么是数组

数组是用来存储一组相同类型的数据的,在内存中是一段连续的空间。

数组的存储:

在这里插入图片描述1. 1. 数组中存放的元素其类型相同 ;
2. 数组的空间是连在一起的;
3. 每个空间有自己的编号,起始位置的编号为0,即数组的下标/索引。

2. 数组的创建及初始化

【数组的创建】

//方式一:定义数组,同时进行初始化(用的最多!!!)
int[] array = {1,2,3,4,5,6};//方式二:定义数组,new开辟内存同时进行初始化。
int[] array = new int[]{1,2,3,4,5,6,};//方式三:只是分配了内存,没有进行初始化。大小是10,内容是0
int[] array = new int[10];
int[] array = new int[]{1,2,3,4,5,6,};

注意:

  • 一般通过 new关键字 实例化对象;
  • Java当中的数组,其实就是一个对象,所以Java中:一些皆对象;
  • 在new的时候会生成一块内存,放12345,里面的编号是多少。

【数组的初始化】

  1. 动态初始化: 在创建数组时,直接指定数组中元素的个数。
int[] array = new int[10];
  1. 静态初始化: 在创建数组时不直接指定数据元素个数,而直接将具体的数据内容进行指定。
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;
array = new int[]{1,2,3,4};//不可以这样写,会报错
int[] array;
array = {1,2,3,4};

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

  • 如果数组中储存元素为基类类型,默认值为基类类型对应的默认值,如:
    在这里插入图片描述

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

3. 数组的使用

3.1 数组中元素的访问
	int[] array = {1,2,3,4,5};array[0] = 99; //修改第一个值System.out.println(array[0]); //99System.out.println(array[6]); //越界或负数,都会报数组越界异常ArrayIndexOutOfBoundsExceptionSystem.out.println(array.length); //5 数组的长度

【注意事项】

  1. 数组是一段连续的内存空间,因此支持随机访问,即通过下标访问快速访问数组中任意位置的元素;
  2. 下标从0开始,介于[0, N)之间不包含N,N为元素个数,不能越界,否则会报出下标越界异常。
3.2 遍历数组
  1. 可以一个一个的输出进行遍历
  2. 也可以用for循环
    【方法1 】
    【代码】
	int[] array = {1,2,3,4,5,6};
//方法1:通过下标来访问for (int i = 0; i < array.length; i++) {System.out.println(array[i]);
}

【输出结果】
在这里插入图片描述
【方法2】
【代码】

//方法2:for-each:和下标没关系,数组中每个元素的类型的变量for (int x : array) {System.out.println(x);
}

【输出结果】
在这里插入图片描述
【方法3】
Java中有个类Arrays,是专门操作数组的。
【代码】

//方法3:用定义好的类String ret = Arrays.toString(array); //有String返回值,所以要接收一下,就在=左边定义StringSystem.out.println(ret);

【输出结果】
在这里插入图片描述

其中:
在所有遍历方法的前面加上Arrays.sort(array);即可对数组里面的值进行排序.

二、数组是引用类型

1. 初始JVM的内存分布

程序最终都是保存在JVM里的,内存是一段连续的存储空间,用来存储程序运行时数据的.比如:

  1. 程序运行时代码需要加载到内存;
  2. 程序运行产生的中间数据要存放在内存;
  3. 程序中的常量也要保存;
  4. 有些数据可能需要长时间存储,而有些数据当方法运行结束后就要被销毁.

其中,JVM 也对使用的内存按照功能的不同进行了划分:
在这里插入图片描述
其中:

  1. Java虚拟机栈(JVM Stack) :就是我们平常所说的栈.与方法调用相关的一些信息,每个方法在执行时,都会先创建一个栈帧,栈帧中包含:局部变量表、操作数栈、动态链接、返回地址以及其他的一些信息,保存的都是与方法执行时相关的写一些信息.比如:局部变量.当方法运行结束后,栈帧就被销毁了,即栈帧中保存的数据也被销毁了.
  2. 堆: JVM所管理的最大内存区域,使用 new 创建的对象都是在对上保存,堆是对着程序开始而创建,随着程序的退出而销毁,堆中的数据只要还有在使用,就不会被销毁.
  3. 方法区: 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据.方法编译出的字节码就是保存在这个区域.
  4. 本地方法栈: 本地方法栈与虚拟机栈的作用类似,之不报保存的内容是Native方法的局部变量.有些版本的JVM实现中(例如HotSpot),本地方法栈和虚拟机栈是一起的.
  5. 程序计数器:只是一个很小的空间,保存下一条执行的指令地址.

关于数组为什么是引用类型变量?
为什么说数组array是引用类型的变量,因为他存了数组的地址

int[] array = {1,2,3};

在这里插入图片描述

  1. 首先,有两块内存,一个是栈(Java虚拟机栈),一个是堆;
  2. 只要是new什么,就是在堆里开辟内存,并且在堆里面开辟了一块内存,存储数组中new出来的内容(1,2,3);
  3. array是局部变量,局部变量的内存在栈上,其中array存的是变量的地址0x111,我们把存了地址的变量叫做引用变量 .

【代码】

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

【运行结果】
在这里插入图片描述
其中:
① " I " 代表是一个整型数组;
② " @ " 符号作为分割;
③ 后面是一个16进制的数字,这个数字暂且代表地址.

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

基本数据类型变量:又称为基本变量,该变量空间中直接存放的是其所对应的值;
**引用数据类型变量:**一般称为对象的引用,其空间中存储的是对象所在空间的地址。
引用变量并不直接存储对象本身,可以简单理解成存储的是对象在堆中空间的起始地址。通过该地址,引用变量便可以去操作对象。 有点类似C语言中的指针,但是Java中引用要比指针的操作更简单。

3. 引用变量

  1. int[] array2 = array1; 代表array2这个引用指向了array1这个引用所指向的对象!
  2. 两个引用同时指向了一个对象
  3. 通过其中任何一个引用,修改这个对象的值,另一个引用去访问的时候,也是被改变的

例1:

  	int[] array1 = {1,2,3,4};array1[0] = 99;int[] array2 = array1;array2[0] = 100;System.out.println(Arrays.toString(array1)); //100 2 3 4System.out.println(Arrays.toString(array2)); //100 2 3 4

如图:
在这里插入图片描述
由此可以看出:
int[] array2 = array1; 代表 array2这个引用 指向了array1这个引用 所指向的对象, array1 和 array2 二者指向一个对象.

例2:

	 public static void main(String[] args) {int[] array1 = {1,2,3,4};int[] array2 = {11,22,33,44};array1 = array2;array1[0] = 1888;System.out.println(Arrays.toString(array1)); // 1888 22 33 44System.out.println(Arrays.toString(array2)); // 1888 22 33 44}

在这里插入图片描述
由图可知:
array1 = array2; 代表array1这个引用,指向了array2这个引用所指向的对象。array1之前的对象就没有任何变量用了,被系统回收;
②此时在0x1230中,两个引用同时指向一个对象;
③通过其中任何一个引用,修改0x123对象的值,另一个引用去访问的时候,也是会被改变的。

4. 认识null

null 在Java中表示“空引用”,也就是一个不指向对象的引用

int[] arr = null; //此时arr这个引用,不指向任何对象
System.out.println(arr[0]);
// 执行结果
Exception in thread "main" java.lang.NullPointerException
at Test.main(Test.java:6)

null 的作用类似于 C 语言中的 NULL (空指针), 都是表示一个无效的内存位置. 因此不能对这个内存进行任何读写操作。 一旦尝试读写, 就会抛出 NullPointerException.
注意:Java中并没有约定 null 和 0 号地址有关联。

三、数组的应用场景

1. 保存数据

//存储 1 2 3,并把1 2 3打印出来
int[] array = {1,2,3};for(int i = 0;i <arr.length; i++){System.out.println(array[i] + " ");}

2. 作为函数的参数

2.1 参数传基本类型

形参的改变,不会影响到实参的值。

	public static void main(String[] args) {int num = 0;func(num);System.out.println("num = " + num);}public static void func(int x) {x = 10;System.out.println("x = " + x);}// 执行结果
x = 10
num = 0

执行过程如图:
在这里插入图片描述
我们发现在func方法中修改形参 x 的值, 不影响实参的 num 值

2.2 参数传数组类型(引用数据类型)
 public static void func1(int[] array) {array = new int[]{22,33,44};}public static void func2(int[] array) {array[0] = 999;}public static void main(String[] args) {int[] array1 = {1,2,3,4};func1(array1);System.out.println(Arrays.toString(array1));  //[1, 2, 3, 4]int[] array2 = {1, 2, 3, 4};func2(array2);System.out.println(Arrays.toString(array2)); //[999, 2, 3, 4]}
}
//执行结果
[1, 2, 3, 4]
[999, 2, 3, 4]

执行过程:
当数组作为参数进行传递的时候,其实还是按值传递,只不过此时的值是一个地址!!那么就会出现两种情况:

关于func1():形参修改指向
在这里插入图片描述
所以此代码,只是改变了形参的指向,并没有改变形参的指向,最后结果打印的是实参。

关于func2():形参修改指向对象的值
在这里插入图片描述
此时,传递的是引用,我们通过引用修改了原来的值。

3. 作为函数的返回值

如:将数组的每个元素都扩大2倍。
方法:调用grow()方法,会给grow方法开辟一块内存

 //将数组的每个元素都扩大2倍!public static int[] grow(int[] array) {//遍历数组中的每个元素for (int i = 0; i < array.length; i++) {array[i] = array[i]*2;}return array;}public static void main(String[] args) {int[] array = {1,2,3,5,9};int[] ret = grow(array);System.out.println(Arrays.toString(array)); //[2, 4, 6, 10, 18]System.out.println(Arrays.toString(ret));  //[2, 4, 6, 10, 18]} 

相当于在同一个对象上进行了修改。

四、二维数组

二维数组本质上也就是一堆数组,只不过每个元素 又是一个一维数组。
可以理解是两行。

【格式】
int[][] array = {{1,2,3} , {4,5,6}}; 两行三列
int[][] array = new int[][]{{1,2,3} , {4,5,6}};
int[][] array = new int[2][3];
不规则的二维数组:int[][] array = new int[2][]; 指定了是两行,没有指定列。

【代码】

//for循环的三组打印方式
public static void main(String[] args) {int[][] array = {{1,2,3},{4,5,6}};for (int i = 0;i < 2,i++) {for (int j = 0;j <3;j++) {System.out.println(array[i][j]);}System.out.println();}}

二维数组的用法和一维数组并没有明显差别,因此我们不再赘述。
同理, 还存在 “三维数组”,“四维数组” 等更复杂的数组, 只不过出现频率都很低。

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

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

相关文章

Cheat Engine修改器检测方案

在游戏安全对抗过程中&#xff0c;有不少外挂的实现基于对游戏内存模块进行修改&#xff0c;这类外挂通常会使用「内存修改器」。 据FairGuard游戏安全数据统计&#xff0c;在游戏面临的众多安全风险中&#xff0c;修改器的占比高达16% 。如此高的占比&#xff0c;修改器的危害…

血糖仪_智能便携式血糖检测仪定制_基于联发科MTK8788血糖仪方案

糖尿病早期通常没有明显的症状&#xff0c;因此很难自己意识到自己已经进入高血糖状态。而且&#xff0c;到医院进行检查需要挂号、门诊和排队等步骤&#xff0c;不仅费时费力&#xff0c;对于父母来说&#xff0c;频繁去医院检查是不现实的&#xff0c;也不舍得这样做。因此&a…

maven-assembly-plugin 自定义打包

我想把input文件夹给打包进去 pom文件 <build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-assembly-plugin</artifactId><executions><execution><!-- 配置执行器 --><i…

vue2 百度地图实现 车在线路上移动 BMap、BMapGL

文章目录 效果BMap 实现vue2 中BMap实现vue2 中使用BMapGL实现 参考文章&#xff1a; 百度地图API实时画出动态运行轨迹&#xff08;一条行驶轨迹&#xff09;&#xff0c;车头实时指向行驶方向&#xff0c;设置角度偏移 下文中可能用到的图片统一放在上面&#xff0c;自取。 …

Halcon threshold_sub_pix (Operator)

read_image(Image,fabrik) threshold_sub_pix(Image,Border,35) dev_display(Border)Image是输入的原始图像&#xff0c;Threshold是设定的阈值&#xff0c;Width和Height是像素值计算区域的大小&#xff0c;ThresholdedRegion是经过分割后得到的二值化结果。 在对图像进行二值…

深眸科技以机器视觉高性能优势,为消费电子行业提供优质解决方案

机器视觉技术近年来发展迅速&#xff0c;基于计算机对图像的处理与分析&#xff0c;能够识别和辨别目标物体&#xff0c;被广泛应用于人工智能、智能制造等领域。 机器视觉凭借着高精度、高效率、灵活性和可靠性等优势&#xff0c;不断推进工业企业生产自动化和智能化进程&…

Anaconda安装教程及多次安装失败原因

Anaconda下载网址 本教程包含两部分&#xff1a;安装教程和多次安装Anaconda导致的失败原因分析 Anaconda安装包官网下载链接 ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/b5be0deb0aef4a81a594df79ddc1cc96.png#pic_center 安装 按以下步骤安装 红色波浪…

UEC++ 探索虚幻5笔记 day11

虚幻5.2.1探索 项目目录探索 C工程一定不能是中文路径&#xff0c;中文项目名&#xff0c;最好全部不要用中文&#xff0c;蓝图项目可以是中文浅浅创建一个空项目&#xff0c;讲解一下之前UE4没有讲解的项目目录文件的分布组成 .vs&#xff1a;文件夹一般是项目编译缓存文件夹…

一维相位解包裹

一维相位解包裹 本文首先介绍最简单的一维的位相解包裹算法。设W是包裹运算符&#xff0c;中是解包裹位相&#xff0c;是包裹的位相。则一维位相解包裹可表示为&#xff1a; 解包裹就是要选取正确的k,满足&#xff1a; 两个相邻像素位相的差值如下&#xff1a; 由式(2-1)和式(2…

C语言——2048完整版

2048是一个简单又有趣的小游戏&#xff0c;相信大家都接触并了解过&#xff0c;那如何通过代码来实现他呢&#xff1f;下面就让我们来一起看看。 目录 1、头文件 2、主函数 3、 StarGame 4、GetNum 5、Show 6、Picture 7、GetButton 8、MergeLeft 9、MergeUp 10、MergeR…

Android平板还能编程?Ubuntu本地安装code-server远程编程写代码

文章目录 1.ubuntu本地安装code-server2. 安装cpolar内网穿透3. 创建隧道映射本地端口4. 安卓平板测试访问5.固定域名公网地址6.结语 1.ubuntu本地安装code-server 准备一台虚拟机,Ubuntu或者centos都可以&#xff0c;这里以VMwhere ubuntu系统为例 下载code server服务,浏览器…

[RK-Linux] 移植Linux-5.10到RK3399(四)| 检查HDMI配置与打开内核LOGO显示

文章目录 一、HDMI二、VOP三、显示内核LOGO一、HDMI RK3399 的 HDMI 接口如图: datasheet 介绍: HDMI 接口各个引脚的作用如下: 接口标签作用HDMI_TX0P HDMI_TX0PA差分信号线,用于传输 HDMI 通道 0 的正向数据HDMI_TX0N HDMI_TX0NA

JavaWeb-Tomcat

1. Web服务器 web服务器由硬件和软件组成&#xff1a; 硬件&#xff1a;计算机系统软件&#xff1a;计算机上安装的服务器软件&#xff0c;安装后可以为web应用提供网络服务。 常见的JavaWeb服务器&#xff1a; Tomcat&#xff08;Apache&#xff09;&#xff1a;应用最广泛的…

数据结构 | 查漏补缺之求叶子结点,分离链接法、最小生成树、DFS、BFS

求叶子结点的个数 参考博文&#xff1a; 树中的叶子结点的个数 计算方法_求树的叶子节点个数-CSDN博客 分离链接法 参考博文 数据结构和算法——哈希查找冲突处理方法&#xff08;开放地址法-线性探测、平方探测、双散列探测、再散列&#xff0c;分离链接法&#xff09;_线性…

如何选择性能测试工具?ab和其它工具的对比分析!

性能测试是保证应用程序高效可靠的重要手段之一&#xff0c;在进行性能测试时&#xff0c;选择合适的性能测试工具非常重要。应当根据测试需求来选择适合的测试工具&#xff0c;本文将会详细介绍ApacheBench&#xff08;简称ab&#xff09;和其他性能测试工具的区别以及如何选择…

Peter算法小课堂—贪心算法

课前思考&#xff1a;贪心是什么&#xff1f;贪心如何“贪”&#xff1f; 课前小视频&#xff1a;什么是贪心算法 - 知乎 (zhihu.com) 贪心 贪心是一种寻找最优解问题的常用方法。 贪心一般将求解过程分拆成若干个步骤&#xff0c;自顶向下&#xff0c;解决问题 太戈编程第…

排序:快速排序(hoare版本)

目录 快速排序&#xff1a; 概念&#xff1a; 动画分析&#xff1a; 代码实现&#xff1a; 代码分析&#xff1a; 代码特性&#xff1a; 常见问题&#xff1a; 快速排序&#xff1a; 概念&#xff1a; 快速排序是Hoare于1962年提出的一种二叉树结构的交换排序方法&a…

【项目日记(一)】高并发内存池项目介绍

&#x1f493;博主CSDN主页:杭电码农-NEO&#x1f493;   ⏩专栏分类:项目日记-高并发内存池⏪   &#x1f69a;代码仓库:NEO的学习日记&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习C   &#x1f51d;&#x1f51d; 项目日记 1. 前言2. 什么是高并发内存池…

《opencv实用探索·十三》opencv之canny边缘检测

1、canny边缘检测应用场景 目标检测&#xff1a; Canny边缘检测可以用于检测图像中的目标边缘&#xff0c;从而帮助识别和定位物体。在目标检测的流程中&#xff0c;边缘通常是检测的第一步。 图像分割&#xff1a; Canny边缘检测可用于图像分割&#xff0c;即将图像划分为具有…

微服务--08--Seata XA模式 AT模式

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 分布式事务Seata 1.XA模式1.1.两阶段提交1.2.Seata的XA模型1.3.优缺点 AT模式2.1.Seata的AT模型2.2.流程梳理2.3.AT与XA的区别 分布式事务 > 事务–01—CAP理论…