ArrayList索引始终返回-1?Java化合物质量百分比计算器报错
问题分析与修复方案
核心错误原因
你遇到的索引返回-1并报错的问题,根源在第64行的两处错误调用:
elementMasses.get(wantedElements.indexOf(i)) * wantedElementsCount.indexOf(i)
wantedElements.indexOf(i):wantedElements是存储元素名称的ArrayList<String>,你传入的i是整数类型,列表里根本不存在整数元素,所以必然返回-1,调用get(-1)直接触发IndexOutOfBoundsException。wantedElementsCount.indexOf(i):同样逻辑错误,wantedElementsCount存的是元素个数的整数,但indexOf(i)是找值等于i的元素索引,不是直接获取当前循环索引对应的元素。
其他逻辑问题
除了直接报错的问题,代码还有几个影响功能正确性的bug:
- 元素质量存储逻辑错误:用
elementMasses.contains(elementMass)判断是否添加质量是错误的——不同元素可能有相同原子质量,会导致后添加的同质量元素无法存储,索引对应关系完全混乱。 - 总质量计算错误:当前代码只是把所有元素的原子质量相加,正确总质量应该是「元素原子质量 × 元素个数」的总和。
- 重复元素处理冗余:当元素已存在时,
wantedElements.add(elementNames.get(elementNames.indexOf(elementID)))完全没必要,直接wantedElements.add(elementID)即可。
修复后的完整代码
import java.util.ArrayList; import java.util.Scanner; import static java.lang.System.in; import static java.lang.System.out; public class Main { static void clearScreen() { out.println("\033[H\033[2J"); out.flush(); } public static void main(String[] args) { String elementID; int totalElements; int elementCount; double elementMass; double totalMass; Scanner sc = new Scanner(in); ArrayList<String> elementNames = new ArrayList<>(); ArrayList<String> wantedElements = new ArrayList<>(); ArrayList<Integer> wantedElementsCount = new ArrayList<>(); ArrayList<Double> elementMasses = new ArrayList<>(); while (true) { out.print("\nEnter amount of elements in compound: "); totalElements = Integer.parseInt(sc.nextLine()); out.println("TOTAL ELEMENTS COUNT: " + totalElements + "\n"); wantedElements.clear(); wantedElementsCount.clear(); for (int elms = 1; elms <= totalElements; elms++) { out.print("Enter name for element #" + elms + " (it will be remembered if spelt correctly): "); elementID = sc.nextLine(); out.println("ENTERED ELEMENT NAME: " + elementID + "\n"); if (!elementNames.contains(elementID)) { elementNames.add(elementID); out.print("Enter mass for element #" + elms + ": "); elementMass = Double.parseDouble(sc.nextLine()); out.println("ENTERED ELEMENT MASS: " + elementMass + "\n"); elementMasses.add(elementMass); } wantedElements.add(elementID); out.print("Enter the amount of the element there is: "); elementCount = Integer.parseInt(sc.nextLine()); out.println("ENTERED ELEMENT AMOUNT: " + elementCount + "\n"); wantedElementsCount.add(elementCount); } // 计算正确的总质量:元素质量 × 对应个数的总和 totalMass = 0; for (int i = 0; i < wantedElements.size(); i++) { String element = wantedElements.get(i); int massIndex = elementNames.indexOf(element); totalMass += elementMasses.get(massIndex) * wantedElementsCount.get(i); } // 计算每个元素的质量百分比 for (int i = 0; i < wantedElements.size(); i++) { String currentElement = wantedElements.get(i); int massIndex = elementNames.indexOf(currentElement); double elementTotalMass = elementMasses.get(massIndex) * wantedElementsCount.get(i); double percentage = (elementTotalMass / totalMass) * 100; out.printf("%% MASS OF %s: %.2f%%\n", currentElement, percentage); } out.println("TOTAL COMPOUND MASS: " + totalMass + "\n"); } } }
修复要点说明
- 索引错误修复:循环中通过
elementNames.indexOf(currentElement)获取元素对应的质量索引,用当前循环的i直接获取wantedElementsCount中对应的个数,避免错误的indexOf(i)调用。 - 总质量计算修正:遍历所有选中元素,计算每个元素的总质量(原子质量×个数)并累加得到化合物总质量。
- 元素存储逻辑修正:移除错误的
elementMasses.contains(elementMass)判断,确保每个新元素的质量都能正确存入列表,和elementNames索引一一对应。 - 冗余代码简化:删除重复元素处理时的冗余代码,直接添加原元素名称。
- 输出优化:用
printf格式化百分比输出,保留两位小数,结果更直观。
内容的提问来源于stack exchange,提问作者Tiimzee
相关产品推荐
相关产品推荐

