
本文讲解如何避免硬编码索引访问二维字符串数组,通过封装数据为实体类并结合集合迭代,安全、清晰、可维护地批量调用绘图方法。
本文讲解如何避免硬编码索引访问二维字符串数组,通过封装数据为实体类并结合集合迭代,安全、清晰、可维护地批量调用绘图方法。
在 Java 开发中,直接使用 String[][] 存储异构结构数据(如图片名、宽、高)虽看似简洁,但极易引发索引越界、逻辑错位和可读性差等问题。你当前的嵌套循环:
for(int i = 0; i <p>存在严重逻辑错误:外层循环遍历列数(ships[0].length),内层却遍历行数(ships.length),且始终固定取 ships[i][0] 等——这会导致 ArrayIndexOutOfBoundsException(当 i ≥ ships.length 时),也无法正确对齐“Bismarck.png–170–20”这一组关联数据。</p><p>✅ 正确解法是<strong>语义建模 + 类型安全</strong>:将每艘战舰的图像信息抽象为独立对象。</p><div class="aritcle_card flexRow artxards">
<div class="artcardd flexRow">
<a class="aritcle_card_img" rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java"><img
src="https://img.php.cn/upload/skill/000/000/081/178955835420587.jpg" alt="Alibabacloud Sdk Client Initialization For Java" onerror="this.onerror='';this.src='/static/lhimages/moren/morentu.png'" ></a>
<div class="aritcle_card_info flexColumn">
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="overflowclass">Alibabacloud Sdk Client Initialization For Java</a>
<p class="overflowclass">在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。</p>
</div>
<a rel="nofollow" href="/xiazai/skill3430" title="Alibabacloud Sdk Client Initialization For Java" class="aritcle_card_btn flexRow flexcenter"><b></b><span>下载</span>
</a>
</div>
</div><h3>1. 定义清晰的数据载体类</h3><pre class="brush:php;toolbar:false;">public class ShipImage {
private final String fileName;
private final int width; // 推荐用 int 替代 String,避免运行时解析
private final int height;
public ShipImage(String fileName, int width, int height) {
this.fileName = fileName;
this.width = width;
this.height = height;
}
// Getter 方法(必要时可加)
public String getFileName() { return fileName; }
public int getWidth() { return width; }
public int getHeight() { return height; }
}? 注意:width 和 height 使用 int 而非 String,既提升类型安全,又避免重复 Integer.parseInt(),减少潜在异常。
2. 初始化数据:使用 List 保持顺序(比 LinkedHashSet 更常用且直观)
import java.util.*;
// 在 main 方法中
List<shipimage> ships = Arrays.asList(
new ShipImage("Bismarck.png", 170, 20),
new ShipImage("Rodney.png", 50, 220)
);
BattleScene scene = new BattleScene(ships);</shipimage>3. 重构 BattleScene:依赖注入 + 增强可读性与可测试性
public class BattleScene {
private final List<shipimage> shipImages;
public BattleScene(List<shipimage> shipImages) {
this.shipImages = Objects.requireNonNull(shipImages, "shipImages must not be null");
}
public void createScene() {
for (ShipImage ship : shipImages) {
drawImage(ship.getFileName(), ship.getWidth(), ship.getHeight(), 250, 7);
}
}
// 假设此方法已存在:drawImage(String file, int w, int h, int x, int y)
private void drawImage(String fileName, int width, int height, int x, int y) {
// 实际绘图逻辑(如 Graphics2D.drawImage(...))
System.out.printf("Drawing %s at (%d,%d) with %dx%d%n",
fileName, x, y, width, height);
}
}</shipimage></shipimage>✅ 关键优势总结:
- 零索引风险:不再依赖 ships[i][j] 的行列假设,消除 ArrayIndexOutOfBoundsException;
- 编译期检查:字段名(getFileName())替代魔法数字下标([0]),IDE 可自动补全、重构安全;
- 扩展友好:后续添加旋转角度、透明度等属性,只需扩展 ShipImage 类,无需修改循环逻辑;
- 符合单一职责原则:数据结构(ShipImage)与业务逻辑(BattleScene)分离,便于单元测试与复用。
⚠️ 补充提醒:若原始二维数组来自外部(如 CSV/JSON 解析),应在解析阶段即完成 String[][] → List
的转换,绝不将原始数组传递至业务逻辑层——这是防御性编程的核心实践。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










