You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中ArrayList在被方法设为非空后长度异常归零的问题排查

问题排查与解决方案

首先,我先帮你梳理下代码里的关键问题,以及导致validResources在placement中变为空的可能原因:

1. 先看最明显的代码逻辑问题

你的detection方法里,checkTime初始值是0,所以循环条件for (int i = 1; i < checkTime+1; i++)等价于i < 1,而i从1开始,这个循环根本不会执行。按照当前代码,detection会直接走到最后返回false,但你说它返回了true,这说明要么你贴代码时漏写了checkTime的赋值逻辑(比如应该是checkTime = buildingTemplate.length或者模板数组的长度),要么这是笔误。这个点必须先修正,否则validResources根本不会被填充。

2. 导致validResources在placement中为空的核心原因

validResources被声明为private static,这意味着它是一个全局唯一的集合实例,整个应用中所有代码都共享它。这种设计很容易导致意外修改:

  • 如果在detection返回true(此时集合有元素)和调用placement之间,有其他代码路径调用了validResources.clear()(比如compare方法的else分支,或者其他地方的直接调用),集合就会被清空。
  • 如果是多线程环境,另一个线程同时调用detection或compare,也可能触发clear操作,直接清空集合。
  • 哪怕是单线程,若你在detection返回true后,又不小心调用了其他会修改这个集合的方法,同样会导致数据丢失。

3. 修复建议与优化方案

方案一:先调试追踪集合变化

在所有修改validResources的地方添加日志,明确集合的变化时机:

// 在match方法添加元素时
validResources.add(toBeChecked);
System.out.println("[DEBUG] Added element, size: " + validResources.size() + " | Thread: " + Thread.currentThread().getName());

// 在compare方法清空时
validResources.clear();
System.out.println("[DEBUG] Cleared collection, size: " + validResources.size() + " | Thread: " + Thread.currentThread().getName());

// 在detection返回true前
System.out.println("[DEBUG] detection returning true, size: " + validResources.size());
return true;

// 在placement方法开头
System.out.println("[DEBUG] placement start, size: " + validResources.size());

通过日志你能清晰看到,是不是在detection和placement之间,集合被意外修改了。

方案二:替换静态集合为局部变量(推荐)

静态集合的全局状态是这类问题的根源,最好的解决方式是把validResources改成局部变量,通过方法参数传递,避免全局共享:

// 修改detection方法,返回有效资源集合
public static List<TownResource> detection(int row, int col, TownResource[][] rArray, ResourceEnum[][][] bT, BuildingEnum buildingType) {
    List<TownResource> validResources = new ArrayList<>();
    int checkTime = bT.length; // 假设bT是模板数组,设置正确的循环次数
    int patternIndex = 0;
    try {
        for (int i = 0; i < checkTime; i++) {
            if (compare(row, col, rArray, bT[patternIndex], buildingType, validResources)) {
                for (TownResource tr : validResources) {
                    tr.setScannedBuilding(buildingType);
                }
                System.out.println("Size at compare: " + validResources.size());
                return validResources;
            }
        }
    } catch (ArrayIndexOutOfBoundsException e){
        e.printStackTrace(); // 打印异常方便排查
    }
    return Collections.emptyList();
}

// 修改compare方法,传入局部集合
private static boolean compare(int row, int col, TownResource[][] rArray, ResourceEnum[][] buildingTemplate, BuildingEnum buildingType, List<TownResource> validResources) {
    validResources.clear(); // 每次检查前清空,避免残留
    for (int r = 0; r < buildingTemplate.length; r++) {
        for (int c = 0; c < buildingTemplate[r].length; c++) {
            if (match(rArray[row+r][col+c], buildingTemplate[r][c], validResources)) {
                // 调试日志可保留
            } else {
                validResources.clear();
                return false;
            }
        }
    }
    return true;
}

// 修改match方法,传入局部集合
private static boolean match(TownResource toBeChecked, ResourceEnum checker, List<TownResource> validResources) {
    if (checker == ResourceEnum.NONE) {
        return true;
    } else if (toBeChecked.getResource() == checker) {
        validResources.add(toBeChecked);
        return true;
    }
    return false;
}

// 调用逻辑修改
List<TownResource> valid = detection(row, col, rArray, bT, buildingType);
if (!valid.isEmpty()) {
    placement(rArray, bArray, building, valid);
}

// 修改placement方法,接收局部集合
public static void placement(TownResource[][] rArray, Building[][] bArray, BuildingEnum building, List<TownResource> validResources) {
    System.out.println(validResources.size());
    for (TownResource tr : validResources) {
        System.out.println("Is this statement firing?");
        System.out.println(tr.getResource());
        tr.setResource(ResourceEnum.NONE);
    }
}

这种方式彻底消除了全局静态集合带来的意外修改风险,代码也更健壮、易维护。

内容的提问来源于stack exchange,提问作者QuantumBlink

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 13:38:11