调用方法时如何让LinkedHashMap新增元素的键自增1
问题根因
键始终为1的核心原因是Java基本类型采用值传递机制:
- 你在
menuItem方法中定义的iTerms、iDef是基本类型局部变量,调用addCard时传入的是这两个值的副本,不是变量本身 addCard方法内部对iTerms、iDef的自增操作,只会修改方法内的副本值,不会影响外层menuItem中的原始变量- 每次调用
addCard时,拿到的初始iTerms、iDef都是0,自增后永远是1,所以存入集合的键一直是1
原代码还存在3个隐藏问题:
- 在
addCard中重复创建Scanner实例,和外层输入流冲突,容易出现输入读取错位 - 如果词汇校验通过存入map后,对应的释义重复,原代码不会回滚已经存入的词汇,会导致两个map的数据长度不匹配
- 定义
LinkedHashMap时没有指定泛型,存在类型安全风险
修复方案
把计数器、Scanner实例、两个存储map都定义为类的成员变量,不要把计数器作为参数传给addCard方法,所有方法直接操作成员变量,就能保留自增状态。
修复后可运行的完整代码如下:
import java.util.LinkedHashMap; import java.util.Scanner; public class FlashCardApp { // 全局共享的存储集合、计数器、输入实例 private final LinkedHashMap<Integer, String> terms = new LinkedHashMap<>(); private final LinkedHashMap<Integer, String> definitions = new LinkedHashMap<>(); private final Scanner scanner = new Scanner(System.in); private int termCount = 0; private int defCount = 0; public void runMenu() { boolean isRunning = true; while (isRunning) { System.out.println("Input the action (add, remove, import, export, ask, exit):"); String action = scanner.nextLine(); switch (action) { case "add": addCard(); break; case "remove": // 自行补全删除逻辑 break; case "import": // 自行补全导入逻辑 break; case "export": // 自行补全导出逻辑 break; case "ask": // 自行补全测试逻辑 break; case "exit": isRunning = false; System.out.println("Bye bye!"); break; default: System.out.println("Unknown action"); } } scanner.close(); } private void addCard() { System.out.println("The card:"); String term = scanner.nextLine(); if (terms.containsValue(term)) { System.out.println("The card \"" + term + "\" already exists."); return; } // 词汇校验通过,键自增后存入 int currentTermKey = ++termCount; terms.put(currentTermKey, term); System.out.println("The definition of the card:"); String def = scanner.nextLine(); if (definitions.containsValue(def)) { System.out.println("The definition \"" + def + "\" already exists."); // 释义重复,回滚已经存入的词汇,保证数据一致 terms.remove(currentTermKey); termCount--; return; } // 释义校验通过,键自增后存入 definitions.put(++defCount, def); System.out.printf("The pair (\"%s\":\"%s\") has been added.%n", term, def); // 调试打印,正式使用可删除 System.out.println("Terms map: " + terms); System.out.println("Definitions map: " + definitions); } public static void main(String[] args) { new FlashCardApp().runMenu(); } }
修复说明
- 计数器
termCount、defCount作为类成员变量全局唯一,每次自增的状态会被保留,新增元素的键会从1开始连续递增 - 全局只使用一个
Scanner实例读取输入,避免多实例导致的输入流问题 - 新增了释义重复时的词汇回滚逻辑,保证两个map的键一一对应,不会出现脏数据
- 给集合加上了明确的泛型定义,消除类型安全警告
- 不需要提前预知录入总数量,循环会一直运行直到用户输入exit退出,完全匹配需求
内容的提问来源于stack exchange,提问作者robot
相关产品推荐
相关产品推荐

