HashMap 存电话号码比 ArrayList 查找快,因 get() 平均 O(1);需统一键大小写、校验手机号格式、用 Properties 持久化、支持 quit/exit 退出指令。
HashMap 存电话号码比 ArrayList 查得快查联系人是电话簿最频繁操作,如果用 ArrayList 存,每次都要遍

HashMap,键设为姓名,值存号码,get() 是 O(1) 平均时间。别为了“学数据结构”硬套链表或树,小应用里 HashMap 就是最优解。
注意点:
HashMap 的键区分大小写,map.get("zhangsan") 和 map.get("ZhangSan") 不一样,建议入库前统一转小写:name.toLowerCase()
HashMap 会覆盖旧值,此时该换 Map> ,但小型应用通常不需支持TreeMap——它排序慢、内存多,除非你真要按字母顺序遍历全部联系人且不介意性能损耗用户输个 "123" 或 "138abcd1234" 进去,后面导出、拨号都会崩。Java 没内置手机号校验,得自己加逻辑:
public static boolean isValidPhone(String phone) {
if (phone == null) return false;
return phone.matches("^1[3-9]\\d{9}$"); // 简单匹配大陆 11 位手机号
}说明:
try-catch 包裹 Long.parseLong()——手机号开头可能是 0,且超长会溢出,字符串正则更安全addContact() 和 updateContact() 开头就调这个方法,校验失败直接返回 false 或抛 IllegalArgumentException
Properties 做本地持久化够用又不依赖数据库不需要 MySQL 或 SQLite。Java 自带的 java.util.Properties 能把姓名→号码映射存成纯文本,人类可读、编辑方便、无额外依赖。
示例写入:
Properties props = new Properties();
props.setProperty("张三", "13812345678");
props.setProperty("李四", "15987654321");
try (FileOutputStream fos = new FileOutputStream("contacts.properties")) {
props.store(fos, "Phonebook data - " + new Date());
}读取时注意:
"contacts.properties"),别写绝对路径,否则换个电脑就打不开Properties.load() 读到的 key/value 都是 String,无需转换,直接塞进 HashMap
new File("contacts.properties").exists() 判断一下,没有就跳过加载,别让程序崩溃小型应用容易写成无限循环,用户只能关终端。至少支持输入 "quit"、"exit" 或 "q" 退出:
Scanner scanner = new Scanner(System.in);
while (true) {
System.out.print(">");
String line = scanner.nextLine().trim();
if ("quit".equalsIgnoreCase(line) || "exit".equalsIgnoreCase(line) || "q".equalsIgnoreCase(line)) {
break;
}
// 处理 add / find / list ...
}容易被忽略的细节:
trim() 后判空再处理,否则 split() 出异常line.split("\\s+", 2) 拆成命令+参数就够了,例如 "find 张三" → ["find", "张三"]
Scanner,也别忘了 scanner.close()——但这里关了会导致 System.in 关闭,所以不关更稳妥实际跑起来最麻烦的不是功能,是用户随手输个空格、大小写、中文顿号当分隔符。先锁死输入格式,再谈结构。