Java多组不同长度随机数组存储 二维数组下标越界问题排查
二维数组实现的报错原因说明
你编写的逻辑抛出java.lang.ArrayIndexOutOfBoundsException的核心是两个关键逻辑疏漏:
- 错误的实例化位置:把二维数组的创建语句放到了最内层的元素填充循环中,每生成一个随机数就新建一次二维数组,之前循环生成的所有数据会被直接丢弃,根本没有长期留存的可能。
- 错误的数组维度长度设置:你写的实例化语句是
int[][] sortableArray = new int[i][n]:- 当外层循环跑到i=0(对应n=100的测试组),新建的二维数组第一维长度为0,没有任何可用的第一维索引,赋值时直接越界;
- 当外层循环跑到i=1(对应n=250的测试组),新建的二维数组第一维长度为1,合法索引只有0,你却要给
sortableArray[1]位置赋值,同样超出索引范围。
适配排序性能测试场景的存储方案
由于你10组测试数组的长度完全不统一(从100到6250不等),Java不支持定义等长规则矩形的二维数组,但可以利用Java二维数组本质是「一维int数组的数组」的特性,实现无额外开销的存储,完全匹配你后续做排序耗时统计的需求。
最优方案:原生二维数组存储
这个方案内存访问效率最高,没有集合框架的额外开销,不会干扰排序性能测试的准确性,实现逻辑需要把数组的实例化放到外层循环之外:
- 在生成逻辑的最开头、外层循环之前,提前创建第一维长度固定为10(和测试规模列表长度一致)的二维数组,第二维暂不指定长度(因为每组数组的长度不同)
- 外层循环遍历每个测试规模n时,先给二维数组对应第一维索引的位置,实例化长度为n的一维int数组
- 内层循环往这个一维数组中填充0-99的随机数,所有生成的数组会一直保留在二维数组中,不会被后续循环覆盖
对应修正后的核心代码:
import java.util.Arrays; public class Testing { public static void arrayGenerator() { int[] elements = {100, 250, 500, 750, 1000, 1250, 2500, 3750, 5000, 6250}; // 提前创建二维数组,第一维长度匹配测试组总数 int[][] allTestArrays = new int[elements.length][]; for (int i = 0; i < elements.length; i++) { int n = elements[i]; // 给当前组的位置分配固定长度的一维数组 allTestArrays[i] = new int[n]; for (int k = 0; k < n; k++) { allTestArrays[i][k] = (int) (Math.random() * 100); } // 保留原有验证打印逻辑 System.out.printf("规模%d的数组长度:%d%n", n, allTestArrays[i].length); } // 后续直接遍历allTestArrays,将每组数组传入排序算法统计耗时即可 } public static void main(String[] args) { Testing arrGen = new Testing(); arrGen.arrayGenerator(); } }
备选方案:ArrayList<int[]>存储
如果你后续需要动态调整测试规模的数量(比如临时新增n=10000的测试组),可以用ArrayList<int[]>替代原生二维数组,灵活性更高:
List<int[]> allTestArrays = new ArrayList<>(); for (int n : elements) { int[] sortableArray = new int[n]; for (int k = 0; k < n; k++) { sortableArray[k] = (int) (Math.random() * 100); } allTestArrays.add(sortableArray); }
这个方案和二维数组的性能差距极小,适合需要频繁调整测试参数的开发阶段。
内容的提问来源于stack exchange,提问作者Eoin
相关产品推荐
相关产品推荐

