当前位置: 首页 > news >正文

JAVA多重数组理解

文章目录

    • 概念
    • 多重数组概念
    • 声明与初始化
      • 1. 声明
      • 2. 初始化方式
        • 方式一:直接字面量初始化(推荐用于小数据)
        • 方式二:指定大小(规则矩形)
        • 方式三:锯齿数组(Jagged Array)— 每行长度不同
    • 访问与修改元素
    • 遍历多重数组
      • 1. 普通 for 循环(知道行列数)
      • 2. 增强 for 循环(for-each,简洁安全)
    • 内存结构(重要理解)
    • 常见使用场景(面试高频)
    • 实用工具方法
      • 1. 获取行列数
      • 2. 深拷贝二维数组(避免引用共享)
    • 常见陷阱 & 注意事项
    • 数组跟链表
    • 扩展:高维数组(了解即可)

概念

在 Java 中,“多重数组”通常指的是多维数组(Multidimensional Arrays),最常见的是二维数组(如矩阵),但也可以有三维、四维等。


多重数组概念

Java 的多重数组本质上是 “数组的数组”(array of arrays),即:

  • 一维数组:int[] arr
  • 二维数组:int[][] matrix → 每个元素是一个 int[]
  • 三维数组:int[][][] cube → 每个元素是一个 int[][]

Java 的多维数组不要求每行长度相同(称为“锯齿数组”或“不规则数组”)。


声明与初始化

1. 声明

int[][] matrix;          // 声明一个二维整型数组
String[][][] data;       // 三维字符串数组

2. 初始化方式

方式一:直接字面量初始化(推荐用于小数据)
int[][] grid = {{1, 2, 3},{4, 5, 6},{7, 8, 9}
};
方式二:指定大小(规则矩形)
int rows = 3, cols = 4;
int[][] mat = new int[rows][cols];  // 3x4 的全 0 矩阵
方式三:锯齿数组(Jagged Array)— 每行长度不同
int[][] jagged = new int[3][];      // 3 行,列数未定
jagged[0] = new int[2];             // 第0行有2列
jagged[1] = new int[5];             // 第1行有5列
jagged[2] = new int[1];             // 第2行有1列

注意:new int[3][4] 是规则数组;new int[3][] 是锯齿数组(需手动初始化每行)。


访问与修改元素

int value = matrix[i][j];     // 读取第 i 行第 j 列
matrix[i][j] = 100;           // 修改

边界检查:Java 会在运行时自动检查下标是否越界(抛出 ArrayIndexOutOfBoundsException)。


遍历多重数组

1. 普通 for 循环(知道行列数)

for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[i].length; j++) {System.out.print(matrix[i][j] + " ");}System.out.println();
}

🔍 matrix.length → 行数
matrix[i].length → 第 i 行的列数(支持锯齿数组!)

2. 增强 for 循环(for-each,简洁安全)

for (int[] row : matrix) {for (int val : row) {System.out.print(val + " ");}System.out.println();
}

推荐:优先使用 for-each,避免下标错误,尤其处理锯齿数组时更安全。


内存结构(重要理解)

Java 的二维数组不是一块连续内存(不像 C/C++),而是:

  • 一个一维数组,每个元素指向另一个一维数组
  • 所以可以每行长度不同(锯齿)
matrix → [ ref0, ref1, ref2 ]↓     ↓     ↓[1,2] [3,4,5] [6]

优势:灵活;劣势:缓存局部性较差(相比连续内存)


常见使用场景(面试高频)

场景示例
矩阵操作旋转矩阵、螺旋遍历、对角线遍历
动态规划二维 DP 表(如 LCS、编辑距离)
图的邻接矩阵graph[i][j] == 1 表示 i→j 有边
棋盘/地图模拟迷宫、岛屿数量、生命游戏
分组存储每行代表一类数据

实用工具方法

1. 获取行列数

int rows = matrix.length;
int cols = matrix[0].length;  // 注意:仅当至少有一行且非空时安全!

✅ 安全写法(处理空数组):

if (matrix == null || matrix.length == 0) return;
int rows = matrix.length;
int cols = matrix[0].length; // 此时可安全访问

2. 深拷贝二维数组(避免引用共享)

int[][] deep = new int[original.length][];
for (int i = 0; i < original.length; i++) {deep[i] = original[i].clone(); // 克隆每一行
}
类型含义特点
浅拷贝(Shallow Copy)复制对象的引用,不复制内部对象新旧数组共享子对象
深拷贝(Deep Copy)递归复制所有层级的对象完全独立,互不影响
数组类型浅拷贝是否安全?如何实现深拷贝
int[], double[] 等基本类型✅ 安全(值拷贝)arr.clone() 即可
String[]⚠️ 表面安全(String 不可变)通常 clone() 足够
int[][](二维基本类型)❌ 不安全循环 + row.clone()
Object[](含可变对象)❌ 不安全需手动深拷贝每个元素(可能递归)

🔔 注意:String 虽是引用类型,但不可变(immutable),所以浅拷贝通常不会出问题。但如果是 StringBuilder[],就必须深拷贝!

误区正确理解
clone() 就是深拷贝”❌ 默认是浅拷贝,除非重写 clone() 方法
Arrays.copyOf() 是深拷贝”❌ 对多维数组仍是浅拷贝
“基本类型数组不需要深拷贝”✅ 正确!因为存的是值,不是引用

常见陷阱 & 注意事项

问题说明
空指针异常matrix 为 null,或某行为 null(锯齿数组未初始化)
列数不一致误以为所有行长度相同,直接用 matrix[0].length 遍历所有行
浅拷贝问题直接赋值导致修改副本影响原数组
内存浪费用二维数组存稀疏矩阵(此时应考虑 Map<Pair, Value> 或稀疏表示)

数组跟链表

数组(Array)和链表(Linked List)是两种最基础、最重要的线性数据结构。它们在内存布局、操作效率、适用场景上有本质区别。掌握它们的差异,是算法设计和系统优化的关键。

特性数组(Array)链表(Linked List)
内存布局连续内存块非连续,靠指针连接
随机访问✅ O(1)(通过下标)❌ O(n)(必须遍历)
插入/删除(中间)❌ O(n)(需移动元素)✅ O(1)(已知节点时)
插入/删除(头部)❌ O(n)(除非用特殊技巧)✅ O(1)
插入/删除(尾部)✅ O(1)(动态数组均摊)✅ O(1)(若有 tail 指针)
空间开销仅数据本身每个节点额外存指针(如 next)
缓存友好性✅ 高(局部性好)❌ 低(内存跳跃)
大小固定?静态数组固定;动态数组可扩容动态伸缩,无需预分配
场景推荐结构原因
需要频繁随机访问(如排序、DP)✅ 数组O(1) 访问
频繁在头部/中间插入删除✅ 链表O(1) 修改指针
元素数量固定或可预估✅ 数组内存紧凑,性能高
实现栈(只操作尾部)✅ 数组 or 链表两者都 O(1)
实现队列(首尾操作)✅ 链表 or 循环数组链表天然支持;数组需循环缓冲
内存敏感(小对象大量存储)✅ 数组链表指针开销大
需要缓存友好(高性能计算)✅ 数组连续内存,预取高效

扩展:高维数组(了解即可)

// 三维数组:3 层,每层 4 行,每行 5 列
int[][][] cube = new int[3][4][5];// 访问
cube[0][1][2] = 10;// 遍历
for (int[][] layer : cube) {for (int[] row : layer) {for (int val : row) {// ...}}
}

📌 实际开发中,三维以上数组较少见,通常用对象封装更清晰。


http://www.dtcms.com/a/586612.html

相关文章:

  • 沈阳网站建设服务苏州室内设计学校
  • 【ISO8601库】Serde 集成模块详解(serde.rs文件)
  • 专业餐饮网站建设芜湖集团网站建设
  • 【SystemGestures】屏蔽鼠标悬浮唤出状态栏和手势导航
  • 嘉兴公司网站制作怎么做网站站长
  • 【C++】内部类和组合类
  • MySQL的锁机制:从全局锁到行级锁的全面剖析
  • 北京品牌网站定制公司网络营销推广方案总结
  • 【开题答辩全过程】以 海水水质监测大数据分析为例,包含答辩的问题和答案
  • 自己怎么1做网站做爰网站视屏
  • wordpress技术博客主题昆明网站快照优化公司
  • SpringBoot面试题03-BeanFactory
  • 单位做网站需要多少钱wordpress进不去仪表盘
  • 滨州网站建设模板建设宁阳网站seo推广
  • 免费咨询律师在线微信嘉兴网站排名优化公司
  • 长兴住房和城乡建设局网站昆明网络公司收费标准
  • phpcmsv9网站建设入门教程禅城网站建设公司
  • 2025年市场上主流的22种物联网传感器类型
  • Java Stream流完全指南:从入门到精通
  • Optuna超参数调优图例解读之超参数重要性图
  • 怎么和网站建设公司签合同建一个自己用的网站要多少钱
  • 数字通信入门
  • computed计算属性
  • 无锡做网站设计ui培训心得
  • 游戏“二开”:在巨人的肩膀上创造新世界
  • 网站 用户体验的重要性wordpress有多个页脚
  • 网站开发与数据库高端网站建设与发展
  • PyQt5 QMultiMap完全指南:深入理解Qt的多值映射容器
  • 公司想制作网站黄埔做网站
  • 大功率绿电制氢电源装置研究