Java数组的使用

前言

       这里我使用的是IDEA编译器进行演示

数组的创建与初始化

创建格式:

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

T表示数组存放的数据类型,N表示数组的大小。
T[] 表示数组的类型。

这里要注意和C语言不同的是C语言使用类似int arr[10]这样的结构进行创建数组,而Java使用int[] 直接表明这就是一个数组,体现了Java语言具有简单性,通俗易懂。

数组有三种初始化方式:

int[] arr1 = new int[10];
int[] arr2 = new int[]{1,2,3,4,5,6};
int[] arr3 = {1,2,3,4,5,6};

我们来拆分一下上面三种方式:
首先类似:

T[] array = new T[N];

这种创建形式时,我们叫作动态初始化,这种的特点就是创建的数组所有的元素都是0.
在这里插入图片描述
在这里插入图片描述
然后就是类似下面的:

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

这种我们称为静态初始化,这种就直接对数组每个元素进行了赋值。

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

这种初始化和上面的是一样的,只是简写而已(少写了new int[]),这种就更方便书写。

静态初始化是不能写类似int[] arr = new int[3]{1,2,3}的,也就是第二个中括号是不可以写大小的,数组的大小编译器会更具{ }里面的数据进行确定~~

如果使用的是动态初始化,不同的类型对应不同的默认值~~

这里特别记忆一下存放boolean类型的数组每一个元素默认值是false
在这里插入图片描述

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

特殊情况

如果你想分步创建的话,你可以使用下面两种形式:

        int[] arr;arr = new int[3];
        int[] arr;arr = new int[]{1,2,3};

下面的创建方式是不允许的:
在这里插入图片描述

数组的访问与遍历

访问一个元素

这里可以直接通过访问数组的单个元素,可以借助下标~~

    public static void main(String[] args) {int[] arr = new int[]{1,2,5,6,8,9,0};System.out.println(arr[2]);}

在这里插入图片描述

遍历数组所有元素

1.可以使用循环来直接遍历数组,和C语言是一样的,当时Java里面我们可以直接使用.length来直接得到数组的大小~~

        int[] arr = new int[]{1,2,5,6,8,9,0};for (int i = 0; i < arr.length; i++) {System.out.print(arr[i]+" ");}

在这里插入图片描述

IDEA编译器可以直接输入fori然后按回车,for循环语句就直接输出来了。

2.我们还可以使用for(数据类型+变量名 :数组名){} 来遍历整个数组元素。

        int[] arr = new int[]{1,2,5,6,8,9,0};for (int x: arr) {System.out.print(x+" ");}

在这里插入图片描述
3.数组直接转字符串,然后直接输出。

        int[] arr = new int[]{1,2,5,6,8,9,0};System.out.println(Arrays.toString(arr));

在这里插入图片描述

我们使用的是Arrays里面封装好的方法,它可以直接将数组转变为字符串[数组每一个元素],每一个元素后面会加一个逗号和空格。

引用类型讲解

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

       这里的基本数据类型就是我之前文章里写过的八大基本数据类型,该变量空间中直接存放的是其所对应的值;而引用数据类型创建的变量,一般称为对象的引用,其空间中存储的是对象所在空间的地址。

数组是实际上就是一个引用类型变量,数组名存放的是数组的地址,数组名的地址实际上就是数组所引用的对象的地址,这个对象就是数组包含的数组内容。

在这里插入图片描述
在这里插入图片描述
我们通过打印数组名,发现这是一堆奇怪的数字组合,这一堆数字中4eec7777就是数组所引用的对象的地址。

JVM内存的分布

JVM内存一共可以划分为五大空间:
在这里插入图片描述

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

这里我们只关心Java虚拟机栈和堆~~
Java虚拟机栈会存放我们定义的变量和方法,数组名也是会存放在这里,而对象则会存放在堆里

我们从上面了解到数组名包含的就是数组所指向的对象的地址,然后我们可以画一下内存图,这里为了方便,只画Java虚拟机栈和堆这两个内存空间。

在这里插入图片描述

练习

我们来画一下内存分布图:

    public static void func1() {int a = 10;int b = 20;int[] arr = new int[]{1,2,3};}

在这里插入图片描述

首先a是基本类型变量,所以a包含的数值就是10,直接入栈,然后是b也是一样,压栈,接着是数组arr压栈,由于数组是应用类型变量,所以是存放的是对象的地址,然后数组压栈~~

    public static void func2() {int[] array1 = new int[3];array1[0] = 10;array1[1] = 20;array1[2] = 30;int[] array2 = new int[]{1,2,3,4,5};array2[0] = 100;array2[1] = 200;array1 = array2;array1[2] = 300;array1[3] = 400;array2[4] = 500;for (int i = 0; i < array2.length; i++) {System.out.println(array2[i]);}}

这里我用视频来演示一下压栈过程:

JVM内存画图

这里我来简单描述一下,首先array1入栈,array1引用的对象放在堆里,由于是动态初始化,所以开始时每一个元素都是0,接着就是修改数组元素。
然后是array2入栈,array2引用的对象放在堆里,由于是静态初始化,所以开始时array2所引用的对象的内容就是1,2,3,4,5;接着是修改了两个数组元素。
array1=array2 相当于把array2的值赋给了array1,也就是array1现在装的是array2所引用的对象的地址,所以array1的数组元素修改也影响到了array2,毕竟这两个变量现在所引用的对象是一样的~~

这里要注意的是如果原本array1所引用的对象是不是现在没有变量去引用了,不用当心内存泄漏,Java是有垃圾回收机制的,所以这块内存如果没有变量去引用就会被回收掉~~

数组传参和返回问题

时刻保持清醒,Java是没有指针的概念,也就意味着你无法进行取地址解引用等操作,这体现了Java的安全性,学过C语言的铁汁们都知道指针是很危险的,一不小心就内存泄漏,野指针非法访问等问题~~

我们来铺垫一下C语言的知识点:

形参的改变是不会影响实参

在Java中的基本类型变量也是一样的:

    public static void number(int a){a += 10;}public static void main(String[] args) {int a = 10;System.out.println(a);}

在这里插入图片描述

但是,在Java中数组名可以像普通变量一样相互赋值,也就是地址可以交换或者改变,从而改变所引用的对象。所以数组名可以直接传参,形参接收实参的内容,意味着形参引用的对象就是实参引用的对象,所以形参修改数组是会影响到对象的,也就意味着实参也跟着修改~~

    public static void increase(int[] array){for (int i = 0; i < array.length; i++) {array[i] *= 2;}}public static void main(String[] args) {int[] arr = new int[]{1,2,3,4};System.out.println(Arrays.toString(arr));System.out.println("扩大两倍后:");increase(arr);System.out.println(Arrays.toString(arr));}

在这里插入图片描述

同样的,如果你在方法里创建好了数组,想要返回数组也是可以的,直接返回数组名即可~~

    public static int[] increase(int[] array){int[] arr = new int[array.length];for (int i = 0; i < array.length; i++) {arr[i] = array[i] * 2;}return arr;}public static void main(String[] args) {int[] arr = new int[]{1,2,3,4};System.out.println(Arrays.toString(arr));System.out.println("扩大两倍后:");int[] arr2 = increase(arr);System.out.println("arr数组:"+Arrays.toString(arr));System.out.println("arr2数组:"+Arrays.toString(arr2));}

在这里插入图片描述

null的介绍

当你创建的数组没有对象时,你可以赋值一个null

int[] arr = null;

在这里插入图片描述

如果你对null的数组进行访问的话,就会报出空指针异常!!!
注意Java确实没有指针的概念,这个空指针异常只是名字就叫作空指针异常而已~~

在这里插入图片描述

Arrays

这个Arrays里面包含很多方法供我们使用,里面也有很多重载,上面我们就知道数组转字符串,这里还有二分查找的方法~~

在这里插入图片描述

这里不一一介绍,想要了解的可以查阅官方帮助文档手册~~
后面的文章我也会去讲解~~

二维数组

二维数组的创建与初始化

先看代码:

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

你要分步也是可以的~~

值得注意的是Java的二维数组如果进行动态初始化是一定要给出行数的~~

我来解释一下:在C语言中我们知道二维数组其实就是有一个又一个一维数组构成的,在Java中我们会明显感受到这个内容。

为什么Java一定要知道二维数组的行数才给创建呢?
二维数组也是引用类型变量,在Java虚拟机栈也是存储的是地址,那这是谁的地址呢?除了自己的地址,那肯定存的是自己的成员(一维数组)的地址
所以如果不知道行数也就不知道要开辟多少个空间来保存多少个地址~~

对比C语言,C语言在传参二维数组的时候为什么要知道二维数组的列数,行数却可以不需要知道呢?
站在C语言的角度,C语言需要开辟一整块空间来保存数组内容,所以C语言是一定要知道这个二维数组的每个成员(也就是一维数组)有多大的,给出列数意味着给出了每一个一维数组的具体大小,这样C语言就可以一次一个一维数组进行开辟空间了,最后二维数组也就随之构建好了,根本就用不到行数。
但是只给行数不给列数就不知道每一个一维数组有多大,就无法进行空间的开辟~~

看到这里大家是不是还有疑惑,就是Java不需要知道一维数组的大小吗?
当然不需要了,可以这样理解,Java中我们需要知道被引用的对象的地址,至于对象是多大不需要关心,我们只需要知道对象的地址~~
所以你会发现其实二维数组的成员(一维数组其实是可以不一样大的)~~

我拿 int[][] array2 = new int[][]{{1, 2, 3}, {4, 5, 6}};来说明一下:
我们来看一下Java这个二维数组内存分布图:
在这里插入图片描述

在这里我们明显看到二维数组实质就是由一维数组构建的~~

我们来验证一下吧:

    public static void main(String[] args) {int[][] array = new int[4][];int[][] array2 = new int[][]{{1,2,3}, {4, 5, 6}};int[][] array3 = {{1,2},{3,4},{5,6}};System.out.println("array:");System.out.println(Arrays.toString(array));System.out.println("array2:");System.out.println(Arrays.toString(array2));System.out.println("array3:");System.out.println(Arrays.toString(array2));}

在这里插入图片描述

注意array是动态初始化,由于存储元素类型为引用类型,所以默认值为null
这里要注意了不要去遍历这种null数组哦~~
否则会报空指针异常的~~

二维数组的访问与遍历

遍历方式一

通过上面的解析,我们如果需要遍历二维数组的话,可以使用两个循环,通过.length来得知数组大小~~

    public static void main(String[] args) {int[][] array = new int[4][];int[][] array2 = new int[][]{{1,2,3}, {4, 5, 6}};int[][] array3 = {{1,2},{3,4},{5,6}};System.out.println("array2:");for (int i = 0; i < array2.length; i++) {for (int j = 0; j < array2[i].length; j++) {System.out.print(array2[i][j]+" ");}System.out.println();}System.out.println("array3:");for (int i = 0; i < array3.length; i++) {for (int j = 0; j < array3[i].length; j++) {System.out.print(array3[i][j]+" ");}System.out.println();}}

在这里插入图片描述

遍历方式二

    public static void print(int[][] array){for (int i = 0; i < array.length; i++) {System.out.println(Arrays.toString(array[i]));}}public static void main(String[] args) {int[][] array = new int[4][];int[][] array2 = new int[][]{{1,2,3}, {4, 5, 6}};int[][] array3 = {{1,2},{3,4},{5,6}};System.out.println("array2:");print(array2);System.out.println("array3:");print(array3);}

在这里插入图片描述

上面提到Java中的二维数组的成员可以不一样大的,我们来看一下吧:

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

在这里插入图片描述

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

在这里插入图片描述

这里我们知道当我们要使用Arrays.toString的时候传参需要传的是数组名(可以理解成地址)~~
之后它就顺着这个地址将数组的内容转换成字符串了~~

二维数组的传参与返回

不同于C语言,二维数组可以直接传参过去,不需要列数的说明,而C语言是一定要把列数传递过去的~~

    public static void print(int[][] array){for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {System.out.print(array[i][j]+" ");}System.out.println();}}public static void main(String[] args) {int[][] array = new int[4][];int[][] array2 = new int[][]{{1,2,3}, {4, 5, 6}};int[][] array3 = {{1,2},{3,4},{5,6}};System.out.println("array2:");print(array2);System.out.println("array3:");print(array3);}

返回二维数组就不多说了,也是可以直接返回的~~

    public static int[][] creatArray(){int[][] arr = {{1},{2,3},{4,8,9}};return arr;}public static void main(String[] args) {int[][] array = creatArray();for (int i = 0; i < array.length; i++) {for (int j = 0; j < array[i].length; j++) {System.out.print(array[i][j]+" ");}System.out.println();}}

在这里插入图片描述

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

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

相关文章

电脑文件x3daudio1 7.dll怎么修复?快速修复x3daudio1 7.dll的方法

你试过电脑文件x3daudio1 7.dll丢失么&#xff1f;如果你有遇到这种情况&#xff0c;那么可能你的某些程序就会启动不了&#xff0c;毕竟这个文件是用来处理音频功能的&#xff0c;那么我们要怎么去修复&#xff1f;下面我们一起来详细的了解电脑文件x3daudio1 7.dll这个文件吧…

作为新型锂离子电池正极材料 磷酸锰铁锂(LMFP)行业发展空间有望扩展

作为新型锂离子电池正极材料 磷酸锰铁锂&#xff08;LMFP&#xff09;行业发展空间有望扩展 磷酸锰铁锂&#xff08;LMFP&#xff09;指在磷酸铁锂基础上添加锰元素而制成的新型磷酸盐类锂离子电池正极材料。磷酸锰铁锂含有橄榄石型结构&#xff0c;生产成本低、能量密度高、绿…

中国GDP空间分布数据集、中国人口空间分布数据集、GDP密度分布、人口密度分布数据、夜间灯光分布数据、土地利用数据、道路网分布数据、乡镇边界分布

引言 GDP&#xff08;国内生产总值&#xff09;是指一个国家或地区所有常驻单位在一定时期内生产的所有最终产品和劳务的市场价值。GDP是表征宏观经济发展状况的基础性指标。GDP是社会经济发展、区域规划和资源环境保护的重要指标之一&#xff0c;通常以行政区为基本统计单元。…

echarts 处理数据

假如 我数据是这样式的 一个数组里边包含两个对象 var data [{ "gender": "female", "height": 161.2, "weight": 51.6 }, { "gender": "female", "height": 167.5, "weight": 59 }] 想转换…

HTML学习|初识表单post和get提交、文本框和单选框、按钮、多选框和下拉框、文本域和文件域、搜索框滑块和简单验证、表单的应用、表单初级验证

初识表单post和get提交 form标签是表单&#xff0c;method控制表单提交方式&#xff0c;get方式&#xff0c;表单填写的参数能够在跳转的url地址中看到&#xff0c;post方式是看不到的&#xff0c;action是向何处跳转表单数据 input标签&#xff0c;且typetext&#xff0c;是…

基于“PLUS模型+”生态系统服务多情景模拟预测实践技术应用

工业革命以来&#xff0c;社会生产力迅速提高&#xff0c;人类活动频繁&#xff0c;此外人口与日俱增对土地的需求与改造更加强烈&#xff0c;人-地关系日益紧张。此外&#xff0c;土地资源的不合理开发利用更是造成了水土流失、植被退化、水资源短缺、区域气候变化、生物多样性…

命令行工具部署达梦数据库 DMDPC(BP 多副本架构)

解达梦数据库DPC集群的主要使用场景&#xff1a; DMDPC 关注和解决的是大数据、计算与存储分离、高可用、支持全部的 SQL 标准、拥有完整的事务处理能力和集群规模能够动态伸缩的业务场景&#xff1a; 大量的复杂查询操作要求优化器能够生成优良的执行计划&#xff0c;并且执…

STM32、GD32驱动PCA9685控制舵机源码分享

一、PCA9685介绍 PCA9685是一种16通道PWM&#xff08;脉宽调制&#xff09;控制器芯片&#xff0c;由NXP Semiconductors公司生产。它具有高速I2C总线接口&#xff0c;可以通过I2C总线与微控制器或其他设备进行通信。PCA9685广泛应用于各种需要精确控制多路PWM信号的应用&…

npm install 卡在reify:rxjs: timing reifyNode的解决办法

今天要逆向跑一个electron&#xff0c;但是npm install一直卡在 reify:element-plus: timing reifyNode:node_modules/lodash Completed in 6664ms这里一动不动&#xff0c;一番研究之后发现可能跟用的镜像有关系&#xff0c;我原本是官方镜像&#xff0c;总感觉第三方镜像有一…

伪装目标检测论文阅读之Dual-SAM(CVPR-2024)

论文&#xff1a;link code&#xff1a;code Fantastic Animals and Where to Find Them:Segment Any Marine Animal with Dual SAM 摘要 作为水下智能的重要支柱&#xff0c;海洋动物分割(MAS)涉及对海洋环境中的动物进行分割。以往的方法在提取长范围上下文特征方面表现不佳…

Python | Leetcode Python题解之第77题组合

题目&#xff1a; 题解&#xff1a; class Solution:def combine(self, n: int, k: int) -> List[List[int]]:ans []path []def dfs(x):remain k - len(path)if not remain:ans.append(list(path))returnif n 1 - x > remain:dfs(x 1)path.append(x)dfs(x 1)path.…

宁夏编程培训中心联络及介绍

版权宁夏编程培训中心 宁夏编程培训中心介绍 AI DuLuo&#xff1a;您好&#x1f91d; 欢迎咨询宁夏编程培训中心&#xff0c;创始人账号 公司介绍及创始人介绍&#xff1a; 在职某地区阿里云计算机有限公司 国内&#xff0c;南非发明专利各一项&#xff0c;腾讯云阿里云专家&am…

vue视图不刷新强制更新数据this.$forceUpdate()

在vue中&#xff0c;更新视图数据&#xff0c;不刷新页面&#xff0c;需要强制更新数据才可以 前言 在对数据就行添加和删除时&#xff0c;发现页面视图不更新&#xff0c;排除发现需要强制更新才可以 点击添加或删除&#xff0c;新增数据和删除就行&#xff0c;但在不使用fo…

内容安全(AV)

防病毒网关&#xff08;AV&#xff09;简介 基于网络侧 识别 病毒文件&#xff0c;工作范围2~7层。这里的网关指的是内网和外网之间的一个关口&#xff0c;在此进行病毒的查杀。在深信服中就有一个EDR设备&#xff0c;该设备就是有两种部署&#xff0c;一个部署在网关&#xf…

51单片机keil编程中遇到的问题(持续更新)

字符无法打印报错 查看特殊功能寄存器名字的时候也会报错&#xff0c;因为无法编译通过&#xff0c;导致头文件的定义内容无法查找 keil编译中 error C127: ‘xx’: invalid storage class 这种一般是在编写头文件或源文件时&#xff0c;在声明函数的结尾没有添加分号&…

在阿里云K8S容器中,部署websocket应用程序的总结

一、背景 有一个websocket应用程序&#xff0c;使用spring boot框架开发&#xff0c;http端口号是6005&#xff0c;提供的是websocket服务&#xff0c;所以它还监听一个8889端口的tcp协议。 现在要把它部署到阿里云的k8s容器里&#xff0c;本文着重描述service层的配置。 因…

《intel开发手册卷1》学习笔记1

1、操作模式 IA-32架构支持三种基本操作模式:保护模式、实地址模式和系统管理模式。操作模式决定了哪些指令和体系结构功能是可访问的: 1&#xff09;保护模式&#xff1a;该模式是处理器的自然状态。保护模式的功能之一是能够在受保护的多任务环境中直接执行“实地址模式”80…

Mac 电脑安装 Raptor 流程图软件的方法

0. 安装逻辑 &#xff08;1&#xff09;运行 raptor&#xff0c;本质上需要 mac 能够运行 windows 程序&#xff0c;因此需要安装 .NET Runtime 7.0&#xff0c;这是微软程序运行必须的文件。 &#xff08;2&#xff09;运行 raptor 还需要安装依赖文件 mono-libgdiplus。 &am…

RabbitMQ - 以 MQ 为例,手写一个 RPC 框架 demo

目录 前言 一、再谈自定义应用层协议 二、再谈 BrokerServer 三、再谈 Connection、Channel 四、Demo a&#xff09;启动服务器 b&#xff09;客户端连接 前言 本篇文章来自于笔者之前写过的一个系列 —— “根据源码&#xff0c;模拟实现 RabbitMQ” 系列&#xff0c…

CentOs9编译C指令报错的一种解决方案

今天使用centos9编译c代码时&#xff0c;显示bash: gcc: command not found... 下图是我的报错页面&#xff0c;依据提示信息安装gcc之后依旧显示失败 找到其中一种解决方式&#xff0c;完美解决&#xff0c;供参考 输入以下指令更新软件包列表&#xff0c;这里需要等待几分…