二维数组的定义
1. 概念
二维数组就是一种数组的数组,其本质上还是一个一维数组,只是它的数据元素又是一个一维数组。如果你对这个概念想象不出来,给大家举个栗子,相信吸烟的同学一下子就会明白。
一根烟 = 一个变量
一包烟 = 20根烟 = 一维数组
一条烟 = 10包烟 = 二维数组
也就是说,我们买的”一条烟“,就是一种”二维数组“,明白了吧?
2. 定义
定义二维数组的基本语法如下:
定义方式一:
元素类型[][] 数组名称;
定义方式二:
元素类型 数组名称[][];
在开发时,第一种定义方式更常用一些。这是数组的定义,我们还要对数组进行初始化。二维数组在初始化时,也分为动态初始化和静态初始化两种情况。我们可以把数组的定义和初始化在多条语句中分开完成,也可以直接放在一个语句中完成。
3. 初始化
3.1 动态初始化
二维数组进行动态初始化时,语法格式如下:
元素类型[][] 数组名称 = new 元素类型[二维数组的长度][一维数组的长度];
例如:
int[][] arr = new int[3][4];
在上述示例中,表示我们定义了一个整型的二维数组arr。3表示在二维数组中有3个一维数组,每个一维数组就是一行;4表示每个一维数组中有4个数据元素,这样就形成了二维数组的4列。这样我们就可以把这个二维数组arr看成是一个3行4列的数组或矩阵,访问二维数组中的某个元素时,需要使用arr[row][col]的形式。所以二维数组中,总的元素个数最多有3*4=12个。
以下是动态初始化的案例代码。
publicclassDemo15 {publicstaticvoidmain(String[] args) {// 二维数组--动态初始化//二维数组在动态初始化时,必须指定二维数组的长度。//创建一个包含了3个一维数组的二维数组,每个一维数组的长度是2。int[][] arr2 = newint[3][2];//给二维数组赋值//给二维数组中的第一个一维数组赋值arr2[0][0] = 111;arr2[0][1] = 222;//给二维数组中的第二个一维数组赋值arr2[1][0] = 333;arr2[1][1] = 444;//给二维数组中的第三个一维数组赋值arr2[2][0] = 555;arr2[2][1] = 666;//二维数组取值System.out.println( "二维数组中第一个元素里的第一个元素"+arr2[0][0]);System.out.println( "二维数组中第一个元素里的第二个元素"+arr2[0][1]);System.out.println( "二维数组中第二个元素里的第一个元素"+arr2[1][0]);System.out.println( "二维数组中第二个元素里的第二个元素"+arr2[1][1]);//获取二维数组的长度System.out.println("二维数组的长度"+arr2.length);System.out.println("二维数组中第一个一维数组的长度"+arr2[0].length);System.out.println("二维数组中第二个一维数组的长度"+arr2[1].length);System.out.println("二维数组中第三个一维数组的长度"+arr2[2].length);}}
注意:我们在对二维数组进行动态初始化时,必须先指定出二维数组的长度,但一维数组的长度可以后续使用前再单独指定。
3.2 静态初始化
二维数组中,每个一维数组的长度并不要求相同,可以各不相同。二维数组进行静态初始化时,语法格式如下:
元素类型[][] 数组名称 = new 元素类型[][]{{一维数组1,一维数组2,一维数组3....};
例如:
int[][] arr = new int[][]{{2,3},{5,2,1},{10,45,22,54}};
但是这种方式的语法显得有些啰嗦,所以在实际开发时,我们一般是采用简化的静态初始化方式,如下所示:
元素类型[][] 数组名称 =m{{一维数组1,一维数组2,一维数组3....};
例如:
int[][] arr = {{2,3},{5,2,1},{10,45,22,54}};
以下是静态初始化的案例代码。
publicclassDemo16 {publicstaticvoidmain(String[] args) {// 二维数组--静态初始化//静态初始化一个二维数组。静态初始化时可以很灵活int[][] arr = {{11,22,33},{66,88}};//给二维数组赋值。//重新给二维数组中第一个一维数组里的第3个数据元素(即33)赋值,用99替换原来的33.arr[0][2] = 99;//重新给二维数组中第二个一维数组里的第1个数据元素(即66)赋值,用77替换原来的66.arr[1][0] = 77;//二维数组取值System.out.println( "二维数组中第一个一维数组里的第一个元素"+arr[0][0]);System.out.println( "二维数组中第一个一维数组里的第二个元素"+arr[0][1]);System.out.println( "二维数组中第二个一维数组里的第三个元素"+arr[0][2]);System.out.println( "二维数组中第二个一维数组里的第一个元素"+arr[1][0]);System.out.println( "二维数组中第二个一维数组里的第二个元素"+arr[1][1]);//获取二维数组的长度System.out.println("二维数组中的长度"+arr.length);System.out.println("二维数组中第一个一维数组的长度"+arr[0].length);System.out.println("二维数组中第二个一维数组的长度"+arr[1].length);}}
以上是定义和初始化二维数组的基本案例,为了加深大家对二维数组的理解,接下来壹哥再设计几个代码案例,巩固二维数组的用法。
4. 扩展案例
4.1 动态初始化的变形写法
如果我们在定义二维数组时,没有给定一维数组的长度,那么在使用数组之前,一定要先对一维数组进行初始化。否则,此时如果直接使用一维数组,就会产生空指针异常java.lang.NullPointerException。
publicclassDemo17 {publicstaticvoidmain(String[] args) {//动态初始化时未限定一维数组的长度int[][] arr = newint[3][];//如果我们在定义二维数组时,没有给定一维数组的长度,那么在使用数组之前,一定要初始化里面的一维数组。//否则,如果直接使用一维数组,就会产生空指针异常java.lang.NullPointerException// arr3[0][0] = 100;//初始化一维数组arr[0] = newint[2];arr[1] = newint[1];arr[2] = newint[4];//给数组赋值arr[0][0] = 1;arr[0][1] = 2;arr[1][0] = 10;arr[2][0] = 100;arr[2][1] = 200;arr[2][2] = 300;arr[2][3] = 400;// 二维数组取值System.out.println("二维数组中的第一个元素中的第一个元素" + arr[0][0]);System.out.println("二维数组中的第一个元素中的第二个元素" + arr[0][1]);System.out.println("二维数组中的第二个元素中的第一个元素" + arr[1][0]);}}
arr[0]=new int[2] 和 arr[1]=new int[1]是在为最高维分配引用空间,也就是限制了最高维能保存数据的最大长度。
4.2 遍历二维数组
因为二维数组中包含若干个一维数组,我们之前遍历一维数组时要使用一个循环,所以我们对二维数组进行遍历时就要使用嵌套的双重循环。当然,for/while/foreach等循环都可以使用。
publicclassDemo18 {publicstaticvoidmain(String[] args) {// 二维数组--遍历//定义一个二维数组int[][] arr = {{11,22,33},{55,66},{77,88,99}};//使用双重for循环,遍历二维数组//第一层循环:遍历二维数组中有几个一维数组for (int i = 0; i < arr.length; i++) {//arr[i]是一维数组//第二层循环:遍历每个一维数组for(int j = 0 ; j < arr[i].length ; j++) {System.out.println("二维数组中第"+(i+1)+"个一维数组里的元素"+arr[i][j]);}}}}
5. 内存分析
对于一个二维数组来说,比如int[][] array={{10,0,0,20,0},{0,30,40,0,0},{0,0,0,0,0}};这个二维数组的结构如下图所示:

array[0]会获取array数组的第1个元素,因为array数组的每个元素都是一个一维数组,因此array[0]指向的数组就是{ 10, 0, 0, 20, 0 },其他的以此类推。
高维数组中的每个数据元素,保存的是低位数组的首地址。所以我们访问array[0]就相当于是在访问二维数组中的第一个一维数组的首地址,这样就可以得到第一个一维数组。
相关文章:

二维数组的定义
1. 概念二维数组就是一种数组的数组,其本质上还是一个一维数组,只是它的数据元素又是一个一维数组。如果你对这个概念想象不出来,给大家举个栗子,相信吸烟的同学一下子就会明白。一根烟 一个变量一包烟 20根烟 一维数组一条烟 …...
SpringMVC--获取请求参数、域对象共享数据
SpringMVC获取请求参数 通过ServletAPI获取 将HttpServletRequest作为控制器方法的形参,此时HttpServletRequest类型的参数表示封装了当前请 求的请求报文的对象 RequestMapping("/testParam") public String testParam(HttpServletRequest request){S…...
2月13日,30秒知全网,精选7个热点
///深圳支持数字经济核心区试点,市民每月免费享有1T网络流量支持基础电信企业、广电企业及互联网企业加快推进全市内容分发网络(CDN)扩容及智能改造行动,优化和完善CDN节点部署,积极利用边缘计算技术,推动互…...

【C++设计模式】学习笔记(2):模式分类与模版方法 Template Method
目录 简介模式分类GOF-23 模式分类从封装变化角度对模式分类重构获得模式 Refactoring to Patterns重构关键技法“组件协作”模式Template Method 模式动机(Motivation)结构化软件设计流程面向对象软件设计流程早绑定与晚绑定模式的定义结构(Structure)要点总结结语简介 He…...
【Swift 60秒】92 - Nil coalescing
0x00 Lesson The nil coalescing operator unwraps an optional and returns the value inside if there is one. If there isn’t a value - if the optional was nil - then a default value is used instead. Either way, the result won’t be optional: it will either b…...
python pip安装的包的路径
以ubuntu为例从一个店家那里拿到的一个ubuntu环境中,同时安装了python3.6和python2.7,又安装了ros,最后pip安装包的位置很混乱,安装的包不知道安装在了哪里。使用vscode的时候需要代码提示,就得找到包的路径࿰…...
个人收藏学习
【默认收藏夹】 CompletableFuture使用详解(全网看这一篇就行) 从头开始学MySQL-------存储过程与存储函数(4) 聊聊支付流程的设计与实现逻辑 聊聊消息中心的设计与实现逻辑 SpringBoot2 整合JTA组件,多数据源事务管理…...

【C++】类和对象---需掌握的功能
目录1.初始化列表1.1构造函数赋值1.2初始化列表格式:编译器执行的顺序:特性:1.3explicit关键字类型替换过程多参数构造函数类型替换(C11)2.static成员编程题3.匿名对象4.友元4.1友元函数4.2友元类5.内部类6.拷贝对象时…...

2.12、进程互斥的软件实现方法
学习提示: 理解各个算法的思想、原理结合上小节学习的 “实现互斥的四个逻辑部分”,重点理解各算法在进入区、退出区都做了什么分析各算法存在的缺陷(结合 “实现互斥要遵循的四个原则” 进行分析) 1、单标志法 算法思想:两个进…...
Java面试题-数据库
数据库相关 MySQL的索引使用 默认会有主键索引。 索引分类:单值索引、复合索引、唯一索引 详细文章 MySQL explain 分析 MySQL通过explain关键字分析SQL的执行计划。(Oracle通过EXPLAIN PLAN FOR sql) IDSELECT_TYPETABLEPARTITIONSTYPEPOSS…...

select 与 where、group by、order by、limit 子句执行优先级比较
当 select 和 其他三种语句的一者或者多者同时出现时,他们之间是存在执行先后顺序的。 他们的优先级顺序是:where > group by > select > order by > limit 目录 1、select 与 where 2、group by 与 where 、select 2、select 与 order…...

【Docker】用开源umami监控你的站点访问量
新年到,祝大家兔年吉祥!🎉 1.介绍 umami是一个开源的站点访问量监看程序,其支持docker部署到自己的服务器上。相比较百度等收费的网站信息监看,这种方式对于小站长来说更加实惠一些 2.docker安装的坑 2.1 docker-co…...

java环境配置
java环境配置步骤下载jdk安装jdk配置环境变量通过控制台命令验证配置是否成功大功告成安装教程: https://blog.csdn.net/m0_37220730/article/details/103585266 下载jdk 若不理解JDK/JRE/JVM的关系,可以点此查看初识Java(概念、版本迭代、…...

Linux系统服务:Apache安装及配置应用
目录 一、Apache安装 1、Apache简介 2、Yum安装 3、编译安装 4、服务管理 5、编译安装实现systemctl服务管理 二、Apache配置应用 1、基础应用 2、隐藏版本号 3、更改监听端口 一、Apache安装 1、Apache简介 Apache即阿帕奇是一款开源的、世界使用排名第一的Web服务…...
动态规划(Dynamic Programming)——背包问题
动态规划(Dynamic Programming) 背包问题 目录动态规划(Dynamic Programming)背包问题01背包问题输入格式输出格式数据范围输入样例输出样例:二维一维完全背包问题多重背包问题输入格式输出格式数据范围输入样例输出样例:数据范围二进制优化分组背包问题…...

JVM学习02:内存结构
JVM学习02:内存结构 1. 程序计数器 1.1、定义 Program Counter Register 程序计数器(寄存器) 作用:是记住下一条jvm指令的执行地址 特点: 是线程私有的不会存在内存溢出 1.2、作用 程序计数器物理上是由寄存器来实…...

6年软件测试经验,从我自己的角度理解自动化测试
接触了不少同行,由于他们之前一直做手工测试,现在很迫切希望做自动化测试,其中不乏工作5年以上的人。 本人从事软件自动化测试已经近6年,从server端到web端,从API到mobile,切身体会到自动化带来的好处与痛楚…...

三种方式查看linux终端terminal是否可以访问外网ping,curl,wget
方法1:ping注意不要用ping www.google.com.hk来验证,因为有墙,墙阻止了你接受网址发回的响应数据。即使你那啥过,浏览器都可以访问Google,terminal里面也是无法得到响应 百度在墙内,所以可以正常拿到响应信…...

【Call for papers】SIGCOMM-2023(CCF-A/计算机网络/2023年2月15日截稿)
ACM SIGCOMM is the flagship annual conference of the ACM Special Interest Group on Data Communication (SIGCOMM). ACM SIGCOMM 2023, the 37th edition of the conference series, will be held in New York City, US, September 10 - 14, 2023. 文章目录1.会议信息2.时…...

Chapter5:机器人感知
ROS1{\rm ROS1}ROS1的基础及应用,基于古月的课,各位可以去看,基于hawkbot{\rm hawkbot}hawkbot机器人进行实际操作。 ROS{\rm ROS}ROS版本:ROS1{\rm ROS1}ROS1的Melodic{\rm Melodic}Melodic;实际机器人:Ha…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
椭圆曲线密码学(ECC)
一、ECC算法概述 椭圆曲线密码学(Elliptic Curve Cryptography)是基于椭圆曲线数学理论的公钥密码系统,由Neal Koblitz和Victor Miller在1985年独立提出。相比RSA,ECC在相同安全强度下密钥更短(256位ECC ≈ 3072位RSA…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...

Selenium常用函数介绍
目录 一,元素定位 1.1 cssSeector 1.2 xpath 二,操作测试对象 三,窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四,弹窗 五,等待 六,导航 七,文件上传 …...
Caliper 配置文件解析:fisco-bcos.json
config.yaml 文件 config.yaml 是 Caliper 的主配置文件,通常包含以下内容: test:name: fisco-bcos-test # 测试名称description: Performance test of FISCO-BCOS # 测试描述workers:type: local # 工作进程类型number: 5 # 工作进程数量monitor:type: - docker- pro…...
在 Spring Boot 项目里,MYSQL中json类型字段使用
前言: 因为程序特殊需求导致,需要mysql数据库存储json类型数据,因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...

Copilot for Xcode (iOS的 AI辅助编程)
Copilot for Xcode 简介Copilot下载与安装 体验环境要求下载最新的安装包安装登录系统权限设置 AI辅助编程生成注释代码补全简单需求代码生成辅助编程行间代码生成注释联想 代码生成 总结 简介 尝试使用了Copilot,它能根据上下文补全代码,快速生成常用…...
ffmpeg(三):处理原始数据命令
FFmpeg 可以直接处理原始音频和视频数据(Raw PCM、YUV 等),常见场景包括: 将原始 YUV 图像编码为 H.264 视频将 PCM 音频编码为 AAC 或 MP3对原始音视频数据进行封装(如封装为 MP4、TS) 处理原始 YUV 视频…...