用ArrayList管理联系人比数组更合理,因其动态扩容且增删查便捷;Contact类需封装name、phone、email并实现Serializable与toString();搜索用trim()后contains();删除须用Iterator.remove()或removeIf();保存优先序列化而非文本拼接。

用 ArrayList 存联系人对象比用数组更合理
数组长度固定,新增删除都要手动复制;ArrayList 动态扩容,增删查都直接支持。别用 String[] 或 Object[] 存姓名、电话这些字段——把联系人封装成类,再用集合管理才符合面向对象逻辑。
关键点:
-
Contact类至少包含name、phone、email字段,加toString()方便打印 - 主程序里声明
ArrayList,不是contacts = new ArrayList(); ArrayList原生类型 - 避免写
contacts.add(new Contact("张三", null, "zs@163.com"))这种空值构造——后续phone为空时toString()容易抛NullPointerException
按姓名模糊搜索必须用 String.contains() 而非 equals()
用户输“张”要能匹配“张三”“张小花”,不是只等全名相等。但注意大小写和空格问题——中文基本不用考虑大小写,但用户可能多敲空格。
实操建议:
立即学习“Java免费学习笔记(深入)”;
- 搜索前先调用
keyword.trim()去首尾空格 - 用
contact.getName().contains(keyword),不要用contact.getName().indexOf(keyword) != -1——语义不清且易错 - 如果未来要支持拼音搜索(比如输“zhang”匹配“张三”),得额外引入
pinyin4j库,不是靠字符串方法能解决的
保存到文件时优先选 ObjectOutputStream 而非文本拼接
新手常把 Contact 对象 toString 后一行行写进 txt,结果读取时要手动拆分、解析、new 对象——出错率高,且不支持嵌套字段或特殊字符。
更稳的做法是序列化:
-
Contact类必须实现Serializable接口,加private static final long serialVersionUID = 1L; - 写入用
ObjectOutputStream包裹FileOutputStream,读取用ObjectInputStream包裹FileInputStream - 注意:序列化文件不可读、不可跨 Java 版本兼容;若需人可读或跨平台(比如导出为 JSON),就得换
Gson或Jackson
try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("contacts.dat"))) {
oos.writeObject(contacts);
} catch (IOException e) {
System.err.println("保存失败:" + e.getMessage());
}
删除联系人后没调用 list.remove() 是最常见内存泄漏点
很多人遍历 ArrayList 时用 for-i 循环,找到匹配项就 break,却忘了执行 contacts.remove(i)。或者用增强 for 循环直接删——这会抛 ConcurrentModificationException。
正确姿势只有两种:
- 用
Iterator的remove()方法(安全、推荐) - 用
ArrayList.removeIf(predicate)(Java 8+,一行搞定) - 绝对不要在增强 for 中调用
list.remove(),也别用 for-i 然后只改标志位不删元素
复杂点在于:用户删完一个联系人,界面要不要自动刷新列表?要不要确认提示?这些不是集合本身的问题,但恰恰是初学者最容易忽略的交互断层。










