Java数组的使用


前言

推荐一个网站给想要了解或者学习人工智能知识的读者,这个网站里内容讲解通俗易懂且风趣幽默,对我帮助很大。我想与大家分享这个宝藏网站,请点击下方链接查看。
https://www.captainbed.cn/f1

Java数组是用于存储固定大小、相同类型数据序列的数据结构,可通过索引


一、数组基本用法

什么是数组

数组是一种数据结构,用于存储相同类型的多个元素。它可以在内存中连续地存储多个元素,并通过索引访问每个元素。数组通常具有固定的大小,一旦创建后,大小不能改变。每个元素在数组中都有一个唯一的索引,可以使用索引来获取或修改特定位置的元素。数组可以用于存储整数、浮点数、字符和其他任意类型的数据。

数组本质上就是让我们能 “批量” 创建相同类型的变量.

注意事项

在 Java 中, 数组中包含的变量必须是 相同类型.

创建数组

基本语法

// 动态初始化
数据类型[] 数组名称 = new 数据类型 [] { 初始化数据 };// 静态初始化
数据类型[] 数组名称 = { 初始化数据 };

代码示例

int[] arr = new int[]{1, 2, 3};int[] arr = {1, 2, 3};
注意事项
  • 静态初始化的时候, 数组元素个数和初始化数据的格式是一致的.

  • 其实数组也可以写成

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

这样就和 C 语言更相似了. 但是我们还是更推荐写成 int[] arr 的形式.

int[] 是一个整体.

数组的使用

代码示例

获取长度 & 访问元素
int[] arr = {1, 2, 3};// 获取数组长度
System.out.println("length: " + arr.length); // 执行结果: 3// 访问数组中的元素
System.out.println(arr[1]); // 执行结果: 2
System.out.println(arr[0]); // 执行结果: 1
arr[2] = 100;
System.out.println(arr[2]); // 执行结果: 100
注意事项
  • 使用 arr.length 能够获取到数组的长度. . 这个操作为成员访问操作符. 在面向对象中会经常用到.
  • 使用 [ ] 按下标取数组元素. 需要注意, 下标从 0 开始计数
  • 使用 [ ] 操作既能读取数据, 也能修改数据.
  • 下标访问操作不能超出有效范围 [0, length - 1] , 如果超出有效范围, 会出现下标越界异常

下标越界

int[] arr = {1, 2, 3};
System.out.println(arr[100]);// 执行结果
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 100at Test.main(Test.java:4)

抛出了 java.lang.ArrayIndexOutOfBoundsException 异常.

使用数组一定要下标谨防越界.

遍历数组

所谓 “遍历” 是指将数组中的所有元素都访问一遍, 不重不漏.

通常需要搭配循环语句.

int[] arr = {1, 2, 3};
for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);
}// 执行结果
1
2
3

使用 for-each 遍历数组

int[] arr = {1, 2, 3};
for (int x : arr) {System.out.println(x);
}// 执行结果
1
2
3

for-eachfor 循环的另外一种使用方式. 能够更方便的完成对数组的遍历. 可以避免循环条件和更新语句写错.

二、数组作为方法的参数

基本用法

代码示例

打印数组内容
public static void main(String[] args) {int[] arr = {1, 2, 3};printArray(arr);
}public static void printArray(int[] a) {for (int x : a) {System.out.println(x);}
}// 执行结果
1
2
3

在这个代码中

  • int[] a 是函数的形参, int[] arr 是函数实参.
  • 如果需要获取到数组长度, 同样可以使用 a.length

理解引用类型

我们尝试以下代码

代码示例

参数传内置类型
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

我们发现, 修改形参 x 的值, 不影响实参的 num 值.

在这里插入图片描述

参数传数组类型
public static void main(String[] args) {int[] arr = {1, 2, 3};func(arr);System.out.println("arr[0] = " + arr[0]);
}public static void func(int[] a) {a[0] = 10;System.out.println("a[0] = " + a[0]);
}// 执行结果
a[0] = 10
arr[0] = 10

我们发现, 在函数内部修改数组内容, 函数外部也发生改变.

此时数组名 arr 是一个 “引用” . 当传参的时候, 是按照引用传参.

针对 int[] arr = new int[]{1, 2, 3} 这样的代码, 内存布局如图:
在这里插入图片描述

  • 当我们创建 new int[]{1, 2, 3} 的时候, 相当于创建了一块内存空间保存三个 int
  • 接下来执行 int[] arr = new int[]{1, 2, 3} 相当于又创建了一个 int[] 变量, 这个变量是一个引用类型, 里面只保存了一个整数(数组的起始内存地址)
  • 接下来我们进行传参相当于 int[] a = arr , 内存布局如图
    在这里插入图片描述
  • 接下来我们修改 a[0] , 此时是根据 0x100 这样的地址找到对应的内存位置, 将值改成 100
    在这里插入图片描述
    此时已经将 0x100 地址的数据改成了 100 .

那么根据实参 arr 来获取数组内容 arr[0] , 本质上也是获取 0x100地址上的数据, 也是 100.

如何理解内存

内存就是指我们熟悉的 “内存”. 内存可以直观的理解成一个宿舍楼. 有一个长长的大走廊, 上面有很多房间.

每个房间的大小是 1 Byte (如果计算机有 8G 内存, 则相当于有 80亿 个这样的房间).

每个房间上面又有一个门牌号, 这个门牌号就称为 地址

内存(Memory)是计算机中用于存储数据和指令的硬件设备。它是计算机的重要组成部分,不仅影响着机器的性能,还直接关系到程序的执行效率。

内存可以分为主存(Main Memory)和辅助存储器(Auxiliary Storage)两种类型。主存是计算机的主要工作空间,它存储了当前正在执行的程序和相关的数据。主存通常是易失性存储器,即当计算机断电时,内存中的数据就会丢失。辅助存储器则是指硬盘、固态硬盘(SSD)等非易失性存储介质,它可以用于长期存储数据。

内存的容量通常以字节(Byte)为单位来衡量,1字节等于8位。常见的内存容量单位有千字节(KB)、兆字节(MB)、千兆字节(GB)和太字节(TB)。内存的容量越大,计算机可以同时存储和处理的数据量就越大。

在计算机中,每个内存单元都有一个唯一的地址,通过这个地址可以访问到其中存储的数据。内存的访问速度很快,相比于辅助存储器,它可以更快地读取和写入数据。这也是为什么计算机将程序和数据加载到内存中进行处理。

内存的管理是计算机系统的重要任务之一。操作系统负责分配和回收内存空间,以确保程序能够正常运行并避免内存泄漏的问题。程序员也需要编写高效的代码,尽量减少内存的占用和浪费,提高程序的性能。

总之,理解内存是理解计算机工作原理的重要一环。通过合理利用内存资源,可以提高计算机的性能和效率。

什么是引用

引用相当于一个 “别名”, 也可以理解成一个指针.

创建一个引用只是相当于创建了一个很小的变量, 这个变量保存了一个整数, 这个整数表示内存中的一个地址

总结

所谓的 “引用” 本质上只是存了一个地址.

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

null

null 在 Java 中表示 “空引用” , 也就是一个无效的引用.

int[] arr = null;
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 号地址的内存有任何关联.

JVM 内存区域划分

一个宿舍楼会划分成几个不同的区域: 大一学生, 大二学生… 计算机专业学生, 通信专业学生…内存也是类似, 这个大走廊被分成很多部分, 每个区域存放不同的数据.

JVM 的内存被划分成了几个区域, 如图所示:
在这里插入图片描述

  • 程序计数器 (PC Register): 只是一个很小的空间, 保存下一条执行的指令的地址.
  • 虚拟机栈(JVM Stack): 重点是存储局部变量表(当然也有其他信息). 我们刚才创建的 int[] arr 这样的存储地址的引用就是在这里保存.
  • 本地方法栈(Native Method Stack): 本地方法栈与虚拟机栈的作用类似. 只不过保存的内容是Native方法的局部变量. 在有些版本的 JVM 实现中(例如HotSpot), 本地方法栈和虚拟机栈是一起的.
  • 堆(Heap): JVM所管理的最大内存区域. 使用 new 创建的对象都是在堆上保存 (例如前面的 new int[]{1, 2, 3} )
  • 方法区(Method Area): 用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据. 方法编译出的的字节码就是保存在这个区域.
  • 运行时常量池(Runtime Constant Pool): 是方法区的一部分, 存放字面量(字符串常量)与符号引用. (注意 从 JDK 1.7 开始, 运行时常量池在堆上).

Native 方法

JVM 是一个基于 C++ 实现的程序. 在 Java 程序执行过程中, 本质上也需要调用 C++ 提供的一些函数进行和操作系统底层进行一些交互. 因此在 Java 开发中也会调用到一些 C++ 实现的函数.

这里的 Native 方法就是指这些 C++ 实现的, 再由 Java 来调用的函数.

我们发现, 在上面的图中, 程序计数器, 虚拟机栈, 本地方法栈被很多个原谅色的, 名叫 Thread(线程) 的方框圈起来了,并且存在很多份. 而 堆, 方法区, 运行时常量池, 只有一份.

JVM栈

在这里插入图片描述

  • 局部变量和引用保存在栈上, new 出的对象保存在堆上.
  • 堆的空间非常大, 栈的空间比较小.
  • 堆是整个 JVM 共享一个, 而栈每个线程具有一份(一个 Java 程序中可能存在多个栈).

数组作为方法的返回值

代码示例

写一个方法, 将数组中的每个元素都 * 2
// 直接修改原数组
class Test {public static void main(String[] args) {int[] arr = {1, 2, 3};transform(arr);printArray(arr);}public static void printArray(int[] arr) {for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}public static void transform(int[] arr) {for (int i = 0; i < arr.length; i++) {arr[i] = arr[i] * 2;}}
}

这个代码固然可行, 但是破坏了原有数组. 有时候我们不希望破坏原数组, 就需要在方法内部创建一个新的数组, 并由方法返回出来

// 返回一个新的数组
class Test {public static void main(String[] args) {int[] arr = {1, 2, 3};int[] output = transform(arr);printArray(output);}public static void printArray(int[] arr) {for (int i = 0; i < arr.length; i++) {System.out.println(arr[i]);}}public static int[] transform(int[] arr) {int[] ret = new int[arr.length];for (int i = 0; i < arr.length; i++) {ret[i] = arr[i] * 2;}return ret;}
}

这样的话就不会破坏原有数组了.

另外由于数组是引用类型, 返回的时候只是将这个数组的首地址返回给函数调用者, 没有拷贝数组内容, 从而比较高效.

三、二维数组

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

基本语法

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

代码示例

public static void main(String [] args){int[][] arr = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}};for (int row = 0; row < arr.length; row++) {for (int col = 0; col < arr[row].length; col++) {System.out.printf("%d\t", arr[row][col]);}System.out.println("");}}// 执行结果
1 2 3 4
5 6 7 8
9 10 11 12

二维数组的用法和一维数组并没有明显差别, 因此我们不再赘述.

同理, 还存在 “三维数组”, “四维数组” 等更复杂的数组, 只不过出现频率都很低.


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

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

相关文章

AI绘画ComfyUI 进阶教程 | 字节最强换脸插件PuLID 详解,还请收藏!

大家好&#xff0c;我是小强 这应当算作是小编分享的换脸工具系列中的又一力作&#xff0c;从最初的roop&#xff0c;到之后的ReActor&#xff0c;再到备受欢迎的InstantID&#xff0c;以及今日重点介绍的字节开源产品——PuLID。 提及PuLID&#xff0c;首要原因并非仅仅在于…

GpuMall智算云:Ubuntu 实例桌面版

基于 ubuntu18.04 安装的桌面版本&#xff0c;桌面使用 xfce4 &#xff0c;集成了 Pytorch2.3.0、cuda11.8、Python3.10、VNC、noVNC、VSCode-Server。 在 镜像市场 选择xfce4-desktop镜像&#xff0c;然后进行创建实例 GpuMall智算云 | 省钱、好用、弹性。租GPU就上GpuMall…

图片分类模型训练及Web端可视化预测(下)——Web端实现可视化预测

Web端实现可视化预测 基于Flask搭建Web框架&#xff0c;实现HTML登录页面&#xff0c;编写图片上传并预测展示页面。后端实现上一篇文章所训练好的模型&#xff0c;进行前后端交互&#xff0c;选择一张图片&#xff0c;并将预测结果展示到页面上。 文章目录 Web端实现可视化预测…

【Spring Security系列】权限之旅:SpringSecurity小程序登录深度探索

作者&#xff1a;后端小肥肠 创作不易&#xff0c;未经允许严禁转载。 姊妹篇&#xff1a; 【Spring Security系列】Spring SecurityJWTRedis实现用户认证登录及登出_spring security jwt 退出登录-CSDN博客 1. 前言 欢迎来到【Spring Security系列】&#xff01;在当今数字化…

海外媒体发稿的关键步骤和投稿策略:如何撰写高质量的新闻稿?国外软文发布平台有哪些?

发布国外新闻稿件是一个涉及多步骤的过程&#xff0c;旨在确保您的新闻稿能够有效覆盖目标受众。以下是一些关键步骤和实用的技巧&#xff0c;帮助你实现海外媒体发稿。 1. 明确目标和受众 首先&#xff0c;明确您发布新闻稿的目标&#xff0c;是为了增加品牌曝光、推出新产品…

【NVM】持久内存的架构

1 内存数据持久化 1.1 数据持久化 持久内存系统包含如下关键组件&#xff1a;微处理器、连接微处理器内存总线上的持久内存模组&#xff08;Persistent MemoryModule&#xff0c;PMM&#xff09;及持久内存上的非易失性存储介质。 使用持久内存来实现数据的持久化&#xff0c…

蓝牙(2):BR/EDR的连接过程;查询(发现)=》寻呼(连接)=》安全建立=》认证=》pair成功;类比WiFi连接过程。

4.2.1 BR/EDR 流程&#xff1a; 查询&#xff08;发现&#xff09;》寻呼&#xff08;连接&#xff09;》安全建立》认证》pair成功 4.2.1.1 查询&#xff08;发现&#xff09;流程Inquiry (discovering) 类比WiFi的probe request/response 蓝牙设备使用查询流程来发现附近的…

【Docker实操】启动redis服务

一、步骤 1、获取redis镜像 执行获取redis镜像命令&#xff1a;docker pull redis。打印镜像清单&#xff0c;可以看到新拉到的redis镜像。 2、创建redis.conf配置文件 linux主机 mkdir -p /root/www/redis/conf touch /root/www/redis/conf/redis.conf cat << EOF &…

vue contextPath的思考

先说我这边的情况&#xff0c;目前项目都是前后端分离开发的&#xff0c;上线有种部署方式&#xff0c;常见的就是前后端分开部署&#xff0c;这是比较常见的&#xff0c;我这边因客户原因&#xff0c;打包一起进行部署比较简单&#xff0c;交付技术运维部方便后期其他现场部署…

基于Matlab卷积神经网络人脸识别

欢迎大家点赞、收藏、关注、评论啦 &#xff0c;由于篇幅有限&#xff0c;只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 一、项目背景与意义 人脸识别作为计算机视觉领域的关键技术之一&#xff0c;具有广泛的应用前景&#xff0c;如安全…

“高考钉子户”唐尚珺决定再战2024年高考

“高考钉子户”唐尚珺决定在2024年再次参加高考&#xff0c;这个选择确实很特别也很有趣。十几年连续参加高考&#xff0c;他已经积累了大量的备考经验和应试技巧。这样的经验对于高考辅导机构来说无疑是非常宝贵的资源&#xff0c;他如果选择去辅导机构当老师&#xff0c;应该…

文章解读与仿真程序复现思路——电力系统保护与控制EI\CSCD\北大核心《基于改进粒子滤波的锂离子电池剩余寿命预测 》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…

vue 点击复制文本到剪贴板

一、首先在vue文件的template中定义复制按钮 <div size"small" v-if"item.prop jadeCode" class"cell-container"><span>{{ scope.row.jadeCode }}</span> <button click"handleCopy(scope.row.jadeCode)" clas…

告别硬编码:Spring条件注解优雅应对多类场景

一、背景 在当今的软件开发中&#xff0c;服务接口通常需要对应多个实现类&#xff0c;以满足不同的需求和场景。举例来说&#xff0c;假设我们是一家2B公司&#xff0c;公司的产品具备对象存储服务的能力。然而&#xff0c;在不同的合作机构部署时&#xff0c;发现每家公司底…

ABB 任务 模块 程序

1&#xff0c;任务由模块组成 &#xff0c; 2&#xff0c;模块分为程序模块和系统模块 3&#xff0c;可以通过新建程序模块和删除程序模块 4.可以在程序模块中构建程序 5&#xff0c;系统模块不能够被删除 6&#xff0c;main 程序主要体现在自动运行中

【Unity AR开发插件】四、制作热更数据-AR图片识别场景

专栏 本专栏将介绍如何使用这个支持热更的AR开发插件&#xff0c;快速地开发AR应用。 链接&#xff1a; Unity开发AR系列 插件简介 通过热更技术实现动态地加载AR场景&#xff0c;简化了AR开发流程&#xff0c;让用户可更多地关注Unity场景内容的制作。 “EnvInstaller…”支…

鸿蒙开发配置官方地图

一共需要配置 p12 p7b cer csr 四个文件 p12文件配置 注意创建文件名必须是.p12 到AGC创建项目 AppGallery Connect 添加自己的项目名称 我没有开启 暂时不需要 看个人需求 下载刚创建的cer证书 回到我的项目中 点击刚创建的项目 点击这里 四个文件齐全了 "metadata&qu…

Python爬取B站视频:封装一下

&#x1f4da;博客主页&#xff1a;knighthood2001 ✨公众号&#xff1a;认知up吧 &#xff08;目前正在带领大家一起提升认知&#xff0c;感兴趣可以来围观一下&#xff09; &#x1f383;知识星球&#xff1a;【认知up吧|成长|副业】介绍 ❤️如遇文章付费&#xff0c;可先看…

跨境电商赛道,云手机到底能不能化繁为简?

当下国内电商背景&#xff1a; 从零售额的数据来看&#xff1a;随着互联网的普及和消费者购物习惯的改变&#xff0c;国内电商市场规模持续扩大。据相关数据显示&#xff0c;网络消费亮点纷呈&#xff0c;一季度全国网上零售额达到了3.3万亿元&#xff0c;同比增长12.4%。这表…

本地centos7+docker+ollama+gpu部署

1、一台有 NVIDIA GPU 驱动的机器 2、Docker CE安装 # 删除旧版本的 Docker&#xff08;如果存在&#xff09; sudo yum remove -y docker docker-common docker-selinux docker-engine # 安装必要的软件包&#xff1a; sudo yum install -y yum-utils device-mapper-persiste…