ArrayList比HashMap更合适,因需支持模糊搜索、分页、插入顺序及重名处理;建议用JSON存文件、统一nextLine()读输入、CSV导出用opencsv自动转义。

用 ArrayList 存联系人比 HashMap 更合适
通讯录核心是「按姓名查、按号码查、支持增删改查、要保留插入顺序」,ArrayList 比用 HashMap(比如以姓名为 key)更稳妥。后者无法直接支持「按手机号模糊搜索」「分页显示前 10 个」这类操作,且重复姓名时会覆盖——现实中完全可能有多个「张伟」。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 定义
Contact类,至少含name、phone、email字段,重写equals()和hashCode()(仅基于phone判重,避免同号多人) - 主存储用
ArrayList,查姓名用stream().filter(c -> c.getName().contains(keyword)).collect(...) - 如需加速单字段精确查询(比如按手机号查),可额外维护一个
Map,但必须和ArrayList同步更新,否则极易不一致
文件存成 JSON 而不是 Properties 或纯文本
Properties 只适合键值对扁平配置,存联系人会把对象强行拍平(如 contact.0.name=张三),读取时要手动拼装;纯文本解析易出错且无结构校验。而 JSON 天然匹配 Java 对象树,可读性强,出错时能快速定位哪一行格式不对。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 用
com.fasterxml.jackson.core:jackson-databind(轻量,无反射黑魔法) - 写入前确保
Contact类有 public getter/setter,或加@JsonProperty注解 - 保存路径用
System.getProperty("user.home") + "/contacts.json",避免硬编码C:\或/tmp - 每次写入先
FileWriter写临时文件,成功后再Files.move()替换原文件——防止程序崩溃导致通讯录清空
命令行交互别用 Scanner.nextLine() 直接读菜单编号
用户输完「1」再按回车,nextLine() 会吃掉回车符;但如果前面用了 nextInt(),它不吞回车,下一次 nextLine() 就立刻返回空字符串——这是新手最常卡住的点,表现为「输入 2 进入添加,结果直接跳回主菜单」。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 统一用
nextLine()读所有输入,再用Integer.parseInt(input.trim())转数字 - 捕获
NumberFormatException,提示「请输入有效数字」而不是抛堆栈 - 菜单选项用
switch (input.trim()),case 中写清楚分支逻辑,别塞一堆 if-else - 退出前加确认:输入
q或quit才真正退出,防误触
导出 CSV 时必须处理 phone 和 name 中的逗号与换行
如果联系人姓名是「张三,研发部」或备注含「入职时间:2023-01-01\n试用期3个月」,直接用 String.join(",", ...) 会导致 CSV 解析错行、列偏移。Excel 打开后数据全乱。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- CSV 字段值必须用双引号包裹:
"张三,研发部",且字段内双引号要转义为两个:"他说:""你好""" - 别手写 CSV 拼接,用
opencsv库的CsvWriter,它自动处理转义 - 导出文件名带时间戳:
contacts_export_20240520.csv,避免覆盖 - 导出后用
Desktop.getDesktop().open(file)自动打开所在目录(Windows/macOS 支持),比让用户去文件管理器里翻更友好
public class ContactExporter {
public static void exportToCsv(List contacts, Path file) throws IOException {
try (CsvWriter writer = new CsvWriter(Files.newBufferedWriter(file), ',')) {
writer.writeRecord("姓名", "手机号", "邮箱");
for (Contact c : contacts) {
writer.writeRecord(c.getName(), c.getPhone(), c.getEmail());
}
}
}
}
Java 通讯录看着简单,真正卡住人的从来不是「怎么存」,而是「怎么不让用户输错、写错、导错、覆盖错」——所有边界检查、异常捕获、文件原子写、CSV 转义,都是在补这些缝隙。










