Java实现最低折扣统计时访问二维字符串数组报ArrayIndexOutOfBoundsException
异常原因定位
数组越界的直接触发逻辑
ArrayIndexOutOfBoundsException: 2 表示你访问input1[i]的第3个元素(索引从0开始)时,该子数组实际长度不足3,触发源是Scanner的读取残留问题:
- 执行
n=sc.nextInt()读取商品总数时,该方法仅识别并读取输入流中的整数,不会消费整数后面跟着的换行符 - 第一次进入商品读取循环时,
sc.nextLine()读到的不是第一行商品内容,而是整数n后面残留的空字符串 - 对空字符串执行
split(",")得到的数组长度仅为1,不存在索引为2的元素,因此计算折扣时直接触发越界。
以样例输入为例的实际读取流程:
输入流原始内容:4\nmobile,10000,20\nshoe,5000,10\nwatch,6000,15\nlaptop,35000,5
sc.nextInt()读取到数值4,此时输入流剩余内容为\nmobile,10000,20\nshoe,5000,10\nwatch,6000,15\nlaptop,35000,5- 第一次循环调用
sc.nextLine()读取到第一个换行前的空内容,拆分后得到长度为1的数组 - 后续3次循环依次读取到3个商品行,最终
input1数组共存储4个元素,第一个元素为长度1的空拆分结果,其余3个元素为长度3的商品信息 - 计算折扣时遍历第一个元素,尝试访问索引2的位置时,直接抛出越界异常。
代码中其他待修正的逻辑问题
- 你定义初始最小值为
32767并标注是int的最高存储值,实际32767是short类型的最大值。如果某件商品的折扣金额大于32767,初始的min_d值会小于真实折扣,导致最小值计算错误,应当使用Integer.MAX_VALUE(int类型的实际最大值)作为初始值。 - 原代码拼接输出字符串时,多个最低折扣的商品末尾会带出多余空格,不符合常规输出格式要求。
修复后可正常运行的代码
import java.util.*; public class Main { public static void main(String[] args) { Scanner sc=new Scanner(System.in); int n = sc.nextInt(); // 消耗nextInt()读取后残留的换行符 sc.nextLine(); String input[]=new String[n]; String input1[][]=new String[n][3]; for(int i=0;i<n;i++) { input[i]=sc.nextLine(); input1[i]=input[i].split(","); } int discount[]=new int[n]; for(int i=0;i<n;i++) { discount[i]=(Integer.parseInt(input1[i][2])*Integer.parseInt(input1[i][1]))/100; } // 使用int类型真实最大值作为初始最小值 int min_d=Integer.MAX_VALUE; for(int i=0;i<n;i++) { if(min_d>discount[i]) min_d=discount[i]; } StringBuilder output=new StringBuilder(); for(int i=0;i<n;i++) { if(discount[i]==min_d) { // 拼接时自动处理间隔空格,避免末尾多余空格 if(output.length() > 0) output.append(" "); output.append(input1[i][0]); } } System.out.println(output); sc.close(); } }
内容的提问来源于stack exchange,提问作者rohith reddy
相关产品推荐
相关产品推荐

