Java初学者项目实战:实现一个联系人管理系统

Java初学者做联系人管理系统,核心是理清对象设计、数据存储(ArrayLis

t)和CRUD流程;Contact类需初始化字段、重写equals/hashCode/toString;操作集合时注意引用、遍历删除、字符串比较等细节。

Java初学者做联系人管理系统,核心不是堆功能,而是理清「对象怎么建」「数据存在哪」「增删改查怎么串起来」。用 ArrayList 存联系人、用 Scanner 做简单交互、不碰数据库和图形界面,是最可控的起点。

联系人实体类怎么设计才不踩空指针和逻辑混乱

别一上来就加一堆 getter/setter 和构造方法。先想清楚:哪些字段是必须的?哪些操作会频繁用到?

  • namephone 是必填项,声明时直接初始化为 "",避免后续判空爆炸
  • 不要用 int id 自增主键——初学阶段手动维护 ID 容易错,改用 ArrayList 的索引隐式标识(比如显示时用 list.indexOf(contact) + 1
  • 重写 equals()hashCode() 很重要:否则用 remove(contact) 会删不掉,因为默认比较的是引用地址
  • toString() 一定要写,调试和打印列表时省去手动拼接
public class Contact {
    private String name = "";
    private String phone = "";

    public Contact(String name, String phone) {
        this.name = name == null ? "" : name.trim();
        this.phone = phone == null ? "" : phone.trim();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Contact contact = (Contact) o;
        return Objects.equals(name, contact.name) && Objects.equals(phone, contact.phone);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, phone);
    }

    @Override
    public String toString() {
        return "Contact{name='" + name + "', phone='" + phone + "'}";
    }
}

用 ArrayList 管理联系人时的典型误操作

很多人写完 add() 就以为完了,结果查不到、删不掉、改无效——问题常出在「对象引用」和「集合操作时机」上。

  • 遍历中直接 remove() 会跳过下一个元素,必须用 Iterator.remove() 或倒序 for 循环
  • 修改联系人不能只改字段值:如果对象已存入 ArrayList,直接 contact.setName("new") 是生效的(因为是引用),但务必确认你操作的是集合里的那个对象,而不是 new 出来的新对象
  • 搜索联系人别用 == 比字符串,要用 .equals();更稳妥是统一转小写再比:contact.getName().toLowerCase().contains(keyword.toLowerCase())
  • 清空列表别写 contacts = new ArrayList(),这只会让变量指向新集合,原引用还在其他地方挂着;要用 contacts.clear()

控制台交互容易卡死或跳过输入的坑

Scanner 读取 nextLine() 前如果刚用了 nextInt()next(),会把换行符留在缓冲区,导致下一次 nextLine() 立刻返回空字符串。

  • 统一用 nextLine() 读所有输入,数字也读成字符串再转:Integer.parseInt(scanner.nextLine().trim())
  • 每次读完做 .trim(),防止用户多敲空格导致匹配失败
  • 菜单循环里别忘了在 switch 外加 default 分支,提示 “输入无效”,否则输错就静默退出
  • 退出前加一句 System.out.println("再见!");,不然程序结束太突兀

为什么不用文件持久化,以及什么时候该加

初学阶段硬上 FileWriterObjectOutputStream,90% 的时间花在解决 FileNotFoundExceptionNotSerializableException、乱码和路径错误上,反而模糊了核心逻辑。

  • 等你能稳定完成「增删改查+搜索+按名排序」且单元测试通过后,再加文件支持
  • 第一版文件保存建议用纯文本每行一个联系人,格式如 张三,13800138000,用 String.split(",") 解析,比序列化简单得多
  • 千万别在每次增删后都全量重写文件——效率低还容易写坏。先内存操作,退出时统一保存

真正卡住初学者的,往往不是语法,而是没意识到「用户输了个空格」「两次 new 出来的对象不是同一个」「Scanner 缓冲区残留了回车」这些细节。把这些点盯住,系统就跑得稳。