java 二维数组大小变化导致报错

问题描述:定义了一个二维数组比如 大小是5 ,,但是在进入 for 循环后,它的大小强制变化,导致报错
报错描述:Index 3 out of bounds for length 2
代码逻辑:先在另一个方法中控制台第一次循环输入 3个 cashInflowsOutFlowsArray,用cashInflowsOutFlowsList.add 方法 循环添加 到cashInflowsOutFlowsList ;然后第二次循环输入2个cashInflowsOutFlowsArray;用cashInflowsOutFlowsList.add 方法 循环添加到 cashInflowsOutFlowsList
这样cashInflowsOutFlowsList就有3+2=5条 二维数组数据。

                  ArrayList<String[][]> cashInflowsOutFlowsList = projectObject.getCashInflowsOutFlows();
                   String[][] cashInflowsOutFlowsArray = new String[cashInflowsOutFlowsList.size()][5];

                   for (int i = 0; i < projectInfoList.size(); i++) {    
             projectInfoArray = projectInfoList.get(i);            
        projectId_a = projectInfoArray[i][0];
                
        // rate of return or discount rate
        r = Double.parseDouble(projectInfoArray[i][3]) / 100;

        System.out.println("cashInflowsOutFlowsList.size: " + cashInflowsOutFlowsList.size());
                
        projectCalculationResultsArray2 = new String[cashInflowsOutFlowsList.size()][5];
        
        for (int j = 0; j < cashInflowsOutFlowsList.size(); j++) {    
                            
            在进入这层循环后,下面的  cashInflowsOutFlowsArray  数组本来长度是5 ,但是强制变成了32 分两批变化。

            cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j);        
                
            System.out.println("j=: " + j);
            
            System.out.println("cashInflowsOutFlowsArray.length=: " + cashInflowsOutFlowsArray.length);
        
            projectId_b = cashInflowsOutFlowsArray[j][0];

“Devil组”引证GPT后的撰写:

  • 根据报错信息 "Index 3 out of bounds for length 2" 可以看出,在使用二维数组时,访问了超出其长度范围的索引,即数组的大小发生了变化。
  • 在代码中,可以看到有一个二维数组 projectInfoArray,其大小可能为 5。在循环中,根据代码 projectInfoArray = projectInfoList.get(i),projectInfoArray 从列表 projectInfoList 中获取,所以其大小可能会因为 projectInfoList 中元素数量的变化而发生变化。
  • 在内层循环中,代码 cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j),同样可能导致 cashInflowsOutFlowsArray 的大小发生变化,因为 cashInflowsOutFlowsList 中的元素数量可能会改变。
  • 因此,当访问这些数组时,需要确保其大小没有发生变化,以免超出其索引范围。如果需要在程序中更改数组的大小,请使用动态数组或其他支持动态大小调整的数据结构。

参考chatGPT的内容和自己的思路,问题原因:在进入循环后,二维数组的大小被强制更改,导致数组下标越界错误。

具体来说,您在循环内部重新定义了一个二维数组 projectCalculationResultsArray2,其大小为 cashInflowsOutFlowsList.size() × 5。但是,在进入内部循环后,您又将另一个二维数组 cashInflowsOutFlowsArray 重新定义为 cashInflowsOutFlowsList.get(j),其大小可能会不同于 projectCalculationResultsArray2,导致数组下标越界错误。

例如,当 cashInflowsOutFlowsList.size() 为3时,projectCalculationResultsArray2 的大小为3 × 5,但是当 j 等于3时,cashInflowsOutFlowsArray 的大小将被强制更改为2 × 5 或其他大小,因此当您尝试访问 cashInflowsOutFlowsArray[j][0] 时,会导致数组下标越界错误。

解决方法:确保在进入内部循环之前,projectCalculationResultsArray2 和 cashInflowsOutFlowsArray 的大小相同。

例如,您可以将 projectCalculationResultsArray2 的大小更改为 cashInflowsOutFlowsList.size() × cashInflowsOutFlowsArray.length,或者在内部循环之前检查 cashInflowsOutFlowsArray 的大小,并将其调整为与 projectCalculationResultsArray2 相同的大小。

代码可以按照如下思路进行修改:

for (int i = 0; i < projectInfoList.size(); i++) {
    projectInfoArray = projectInfoList.get(i);
    projectId_a = projectInfoArray[i][0];

    // rate of return or discount rate
    r = Double.parseDouble(projectInfoArray[i][3]) / 100;

    System.out.println("cashInflowsOutFlowsList.size: " + cashInflowsOutFlowsList.size());

    // 将 projectCalculationResultsArray2 的大小更改为与 cashInflowsOutFlowsArray 相同的大小
    projectCalculationResultsArray2 = new String[cashInflowsOutFlowsList.size()][cashInflowsOutFlowsArray.length];

    for (int j = 0; j < cashInflowsOutFlowsList.size(); j++) {
        cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j);
        System.out.println("j=: " + j);
        System.out.println("cashInflowsOutFlowsArray.length=: " + cashInflowsOutFlowsArray.length);

        // 在进入内部循环之前检查 cashInflowsOutFlowsArray 的大小
        if (cashInflowsOutFlowsArray.length != projectCalculationResultsArray2[0].length) {
            // 将 cashInflowsOutFlowsArray 的大小调整为与 projectCalculationResultsArray2 相同的大小
            String[][] resizedArray = new String[cashInflowsOutFlowsList.size()][projectCalculationResultsArray2[0].length];
            for (int k = 0; k < cashInflowsOutFlowsArray.length; k++) {
                resizedArray[j][k] = cashInflowsOutFlowsArray[k];
            }
            cashInflowsOutFlowsArray = resizedArray[j];
        }

        projectId_b = cashInflowsOutFlowsArray[0];
        // 其他处理逻辑
    }
}

回答不易,还请采纳!!!

参考GPT和自己的思路,根据你提供的代码,我发现问题可能出在以下两行代码上:

projectInfoArray = projectInfoList.get(i);            
projectId_a = projectInfoArray[i][0];

在这里,你将 projectInfoArray 的值赋值为 projectInfoList.get(i),然后在下一行尝试访问 projectInfoArray[i][0],这会导致 Index 3 out of bounds for length 2 的错误,因为 projectInfoArray 的大小是根据 projectInfoList.get(i) 来动态分配的,而不是固定的大小为5。

为了解决这个问题,你需要根据 projectInfoList.get(i) 的大小动态分配 projectInfoArray,而不是尝试访问一个固定的大小为5的数组。修改后的代码如下:

for (int i = 0; i < projectInfoList.size(); i++) {
    projectInfoArray = projectInfoList.get(i);
    int projectInfoArraySize = projectInfoArray.length; // 获取 projectInfoArray 的大小
    projectId_a = projectInfoArray[0][0];
    // rate of return or discount rate
    r = Double.parseDouble(projectInfoArray[0][3]) / 100;
    System.out.println("cashInflowsOutFlowsList.size: " + cashInflowsOutFlowsList.size());
    projectCalculationResultsArray2 = new String[cashInflowsOutFlowsList.size()][5];
    for (int j = 0; j < cashInflowsOutFlowsList.size(); j++) {
        // 动态分配 cashInflowsOutFlowsArray
        cashInflowsOutFlowsArray = new String[cashInflowsOutFlowsList.get(j).length][5];
        cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j);
        System.out.println("j=: " + j);
        System.out.println("cashInflowsOutFlowsArray.length=: " + cashInflowsOutFlowsArray.length);
        projectId_b = cashInflowsOutFlowsArray[0][0];
    }
}


在这里,我添加了一行 projectInfoArraySize 来获取 projectInfoArray 的大小,并在内部循环中动态分配 cashInflowsOutFlowsArray。这样就可以避免数组大小发生变化导致的错误。

根据你提供的代码和报错信息,可以看出问题出在 cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j); 这一行代码上。

在进入循环时,你通过 projectCalculationResultsArray2 = new String[cashInflowsOutFlowsList.size()][5]; 定义了一个二维数组 projectCalculationResultsArray2,其中第一维的大小为 cashInflowsOutFlowsList.size(),这个大小没有问题。

但在进入循环后,你又通过 cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j); 重新定义了一个二维数组 cashInflowsOutFlowsArray,其中第一维的大小是 cashInflowsOutFlowsList.size(),这个大小也没有问题。但是在第二维上,你使用了变量 j 来作为索引,这个变量的范围是从0到 cashInflowsOutFlowsList.size() - 1。所以当 j 的值大于等于3时,就会超出 cashInflowsOutFlowsArray 的第二维范围,导致了 Index 3 out of bounds for length 2 的错误。

解决这个问题的方法是,确保在进入循环后,重新定义的数组 cashInflowsOutFlowsArray 的大小与你预期的大小相同,或者在使用 j 作为索引时,确保它不会超出数组的范围。

根据你提供的代码和问题描述,我假设你想要定义一个二维数组 projectCalculationResultsArray2,它的第一维大小为 cashInflowsOutFlowsList.size(),第二维大小为 5。同时,你想要使用 cashInflowsOutFlowsArray 数组来存储 cashInflowsOutFlowsList 中的元素,并在循环中使用。

根据这个理解,你可以在循环外部定义 projectCalculationResultsArray2 数组,然后在循环中使用它,而不是重新定义 cashInflowsOutFlowsArray。在循环中,你可以使用 j 作为第一维的索引,而不是第二维的索引。这样,你就可以避免超出数组范围的问题。

以下是可能的修正代码:

// Define projectCalculationResultsArray2 outside the loop
String[][] projectCalculationResultsArray2 = new String[cashInflowsOutFlowsList.size()][5];

for (int i = 0; i < projectInfoList.size(); i++) {
    projectInfoArray = projectInfoList.get(i);            
    projectId_a = projectInfoArray[i][0];

    // rate of return or discount rate
    r = Double.parseDouble(projectInfoArray[i][3]) / 100;

    System.out.println("cashInflowsOutFlowsList.size: " + cashInflowsOutFlowsList.size());

    // Do not redefine cashInflowsOutFlowsArray, use the one defined outside the loop
    // Use j as the first dimension index, instead of the second dimension index
    for (int j = 0; j < cashInflowsOutFlowsList.size(); j++) {            
        String[] cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j);        

        System.out.println("j=: " + j);

        System.out.println("cashInflowsOutFlowsArray.length=: " + cashInflowsOutFlowsArray.length);

        projectId_b = cashInflowsOutFlowsArray[0];  // Use 0 as the second dimension index

        // Store the results in projectCalculationResultsArray2
        projectCalculationResultsArray2[j][0] = projectId_a;
        projectCalculationResultsArray2[j][1] = projectId_b;
        projectCalculationResultsArray2[j][2] = cashInflowsOutFlowsArray[1];
        projectCalculationResultsArray2[j][3] = cashInflowsOutFlowsArray[2];
        projectCalculationResultsArray2[j][4] = calculateNPV(cashInflowsOutFlowsArray, r);
    }
}


注意,在这个修正代码中,我假设你想要将一些计算结果存储在 projectCalculationResultsArray2 中,并使用 j 作为第一维索引来存储这些结果。如果你的目的不同,请相应地调整代码。

这个问题的根本原因是在进入内层循环后,二维数组 cashInflowsOutFlowsArray 的大小发生了变化,导致在访问其元素时超出了数组的实际大小。

具体来说,在代码中使用了变量 j 来遍历 cashInflowsOutFlowsList 中的元素,然后将其中的元素赋值给 cashInflowsOutFlowsArray。然后,在访问 cashInflowsOutFlowsArray 的元素时,使用了变量 j 来索引数组的第一个维度,使用了变量 i 来索引数组的第二个维度。

然而,问题是在进入内层循环后,cashInflowsOutFlowsArray 的大小发生了变化,导致在使用 j 来索引第一个维度时超出了其实际大小。具体来说,cashInflowsOutFlowsArray 的大小在第一次迭代时变成了 3x2,因此在第二次迭代时,当 j 等于 2 时,访问 cashInflowsOutFlowsArray[j][0] 就会导致越界错误。

要解决这个问题,需要检查代码中的 cashInflowsOutFlowsList 变量,找出在什么地方导致了 cashInflowsOutFlowsArray 的大小发生变化,并确保在访问数组元素时不会超出其实际大小。如果必要,可以在进入内层循环之前,显式地检查 cashInflowsOutFlowsArray 的大小,并根据需要进行调整。

以下答案由GPT-3.5大模型与博主波罗歌共同编写:
根据您提供的代码,可以看出问题出在这里:

cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j);        
System.out.println("j=: " + j);
System.out.println("cashInflowsOutFlowsArray.length=: " + cashInflowsOutFlowsArray.length);
projectId_b = cashInflowsOutFlowsArray[j][0];

通过 cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j); 语句,您将 cashInflowsOutFlowsArray 重新赋值为了从 cashInflowsOutFlowsList 中取出的二维数组。而在进入循环之前,您已经定义了 cashInflowsOutFlowsArray 数组的大小为 [cashInflowsOutFlowsList.size()][5],此时大小为 5。但是在进入循环过程中,通过 cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j); 语句,您将 cashInflowsOutFlowsArray 重新赋值为了从 cashInflowsOutFlowsList 中取出的二维数组,而这个二维数组的大小可能不同,不一定是 5。因此,当您在 projectId_b = cashInflowsOutFlowsArray[j][0]; 中使用 j 作为索引时,出现了 Index 3 out of bounds for length 2 错误,因为此时 cashInflowsOutFlowsArray 的长度可能不足 32

所以,您需要在进入循环之前重新定义 cashInflowsOutFlowsArray 的大小,使其能够适应从 cashInflowsOutFlowsList 中取出的所有二维数组。如下所示:

ArrayList<String[][]> cashInflowsOutFlowsList = projectObject.getCashInflowsOutFlows();
int numOfCashFlows = cashInflowsOutFlowsList.size();
int numOfPeriods = cashInflowsOutFlowsList.get(0).length; //假设所有的二维数组都长度相等
String[][] cashInflowsOutFlowsArray = new String[numOfCashFlows][numOfPeriods];

for (int i = 0; i < projectInfoList.size(); i++) {
    // ...
    for (int j = 0; j < numOfCashFlows; j++) {
        cashInflowsOutFlowsArray = cashInflowsOutFlowsList.get(j);
        // ...
        projectId_b = cashInflowsOutFlowsArray[j][0];
    }
}

通过这种方式,您就可以在循环中正确使用 cashInflowsOutFlowsArray 了。
如果我的回答解决了您的问题,请采纳!

问题出现在第二个for循环中,当j=2时,cashInflowsOutFlowsArray数组的长度为2,但是下面的语句尝试获取cashInflowsOutFlowsArray[j]的第三个元素,导致了"Index 3 out of bounds for length 2"的报错。

可能是在之前的代码中,你已经把cashInflowsOutFlowsArray赋值给了cashInflowsOutFlowsList的某个元素,使得cashInflowsOutFlowsArray的长度发生了改变,导致在后面的代码中出现问题。建议在这部分代码中先检查一下这个数组的长度是否符合预期,并且尽量避免在循环中改变数组的长度。

在进入内层循环后,cashInflowsOutFlowsArray的长度被强制变化是因为在循环中重新为其赋值了。如果你想要保持数组的长度不变,可以使用另一个数组来保存内层循环中的值。可以尝试将代码修改为如下形式:

ArrayList<String[][]> cashInflowsOutFlowsList = projectObject.getCashInflowsOutFlows();
String[][] cashInflowsOutFlowsArray = new String[cashInflowsOutFlowsList.size()][5];
String[][] projectCalculationResultsArray2;
for (int i = 0; i < projectInfoList.size(); i++) {

    projectInfoArray = projectInfoList.get(i);            
    projectId_a = projectInfoArray[i][0];
            
    // rate of return or discount rate
    r = Double.parseDouble(projectInfoArray[i][3]) / 100;

    System.out.println("cashInflowsOutFlowsList.size: " + cashInflowsOutFlowsList.size());
            
    projectCalculationResultsArray2 = new String[cashInflowsOutFlowsList.size()][5];

    for (int j = 0; j < cashInflowsOutFlowsList.size(); j++) {
        String[][] tempArray = cashInflowsOutFlowsList.get(j); // 用tempArray保存内层循环中的值
        System.out.println("j=: " + j);
        System.out.println("tempArray.length=: " + tempArray.length);

        projectId_b = tempArray[j][0];
        // 处理逻辑...
        // 将结果保存到projectCalculationResultsArray2中
    }
}

请注意,这里在内层循环中使用了tempArray数组来保存循环中的值,以防止cashInflowsOutFlowsArray的长度变化影响循环。你需要根据你的具体需求,将处理逻辑部分补充完整,并将结果保存到projectCalculationResultsArray2中。