259 lines
8.9 KiB
Java
259 lines
8.9 KiB
Java
package addressbook;
|
||
|
||
import java.util.*;
|
||
|
||
/**
|
||
* 第 7 天综合项目 —— 命令行通讯录
|
||
*
|
||
* 综合运用本周所学:
|
||
* 1. 类与对象(Contact 内部类)
|
||
* 2. 封装(private 属性 + getter/setter)
|
||
* 3. 集合框架(HashMap 存储,ArrayList 排序)
|
||
* 4. 流程控制(while 菜单循环 + switch 分支)
|
||
* 5. 异常处理(try-catch)
|
||
* 6. 方法封装(每个功能一个方法)
|
||
*/
|
||
public class AddressBookApp {
|
||
|
||
private static final Scanner scanner = new Scanner(System.in);
|
||
// 核心数据结构:以姓名为 key,Contact 对象为 value
|
||
private static final Map<String, Contact> contacts = new LinkedHashMap<>();
|
||
// LinkedHashMap 保持插入顺序,方便"查看全部"时有序展示
|
||
|
||
public static void main(String[] args) {
|
||
System.out.println("============================================");
|
||
System.out.println(" 📒 命令行通讯录 v1.0");
|
||
System.out.println(" 你的第一个 Java 项目!");
|
||
System.out.println("============================================");
|
||
|
||
// 预置几条测试数据,方便快速体验
|
||
initSampleData();
|
||
|
||
// 主循环
|
||
while (true) {
|
||
printMenu();
|
||
int choice = readChoice();
|
||
if (!executeChoice(choice)) {
|
||
break; // 用户选择退出
|
||
}
|
||
}
|
||
}
|
||
|
||
// ==================== 菜单 ====================
|
||
|
||
static void printMenu() {
|
||
System.out.println("\n-----------------------------------------");
|
||
System.out.println(" 1. 添加联系人");
|
||
System.out.println(" 2. 查看全部联系人");
|
||
System.out.println(" 3. 搜索联系人");
|
||
System.out.println(" 4. 修改联系人");
|
||
System.out.println(" 5. 删除联系人");
|
||
System.out.println(" 6. 退出");
|
||
System.out.println("-----------------------------------------");
|
||
System.out.print("请输入你的选择 (1-6): ");
|
||
}
|
||
|
||
static int readChoice() {
|
||
try {
|
||
return scanner.nextInt();
|
||
} catch (InputMismatchException e) {
|
||
scanner.nextLine(); // 清掉无效输入
|
||
return -1;
|
||
}
|
||
}
|
||
|
||
/** @return false 表示用户选择了退出 */
|
||
static boolean executeChoice(int choice) {
|
||
scanner.nextLine(); // 清除换行符(nextInt 不会消耗换行符)
|
||
|
||
switch (choice) {
|
||
case 1 -> addContact();
|
||
case 2 -> listContacts();
|
||
case 3 -> searchContact();
|
||
case 4 -> updateContact();
|
||
case 5 -> deleteContact();
|
||
case 6 -> {
|
||
System.out.println("\n再见!👋");
|
||
scanner.close();
|
||
return false;
|
||
}
|
||
default -> System.out.println("⚠ 无效选项,请输入 1-6。");
|
||
}
|
||
return true;
|
||
}
|
||
|
||
// ==================== CRUD 操作 ====================
|
||
|
||
/** 1. 添加联系人 */
|
||
static void addContact() {
|
||
System.out.println("\n--- 添加联系人 ---");
|
||
|
||
String name = readInput("姓名: ");
|
||
// 校验:姓名不能为空
|
||
if (name.trim().isEmpty()) {
|
||
System.out.println("⚠ 姓名不能为空!");
|
||
return;
|
||
}
|
||
// 校验:不允许重名(HashMap 的 key 唯一)
|
||
if (contacts.containsKey(name)) {
|
||
System.out.println("⚠ 联系人 [" + name + "] 已存在!如需修改请选择功能 4。");
|
||
return;
|
||
}
|
||
|
||
String phone = readInput("电话: ");
|
||
String email = readInput("邮箱: ");
|
||
String address = readInput("地址: ");
|
||
|
||
Contact c = new Contact(name, phone, email, address);
|
||
contacts.put(name, c);
|
||
System.out.println("✅ 联系人 [" + name + "] 已添加!");
|
||
}
|
||
|
||
/** 2. 查看全部联系人 */
|
||
static void listContacts() {
|
||
System.out.println("\n--- 全部联系人 ---");
|
||
|
||
if (contacts.isEmpty()) {
|
||
System.out.println("通讯录为空,快去添加第一个联系人吧!");
|
||
return;
|
||
}
|
||
|
||
// 打印表头
|
||
System.out.printf("%-4s %-12s %-16s %-20s %-20s\n", "序号", "姓名", "电话", "邮箱", "地址");
|
||
System.out.println("---- ------------ ---------------- -------------------- --------------------");
|
||
|
||
int index = 1;
|
||
for (Contact c : contacts.values()) {
|
||
System.out.printf("%-4d %-12s %-16s %-20s %-20s\n",
|
||
index++, c.name, c.phone, c.email, c.address);
|
||
}
|
||
System.out.println("\n共 " + contacts.size() + " 个联系人。");
|
||
}
|
||
|
||
/** 3. 搜索联系人(支持姓名精确搜索,以及姓名/电话的模糊搜索) */
|
||
static void searchContact() {
|
||
System.out.println("\n--- 搜索联系人 ---");
|
||
String keyword = readInput("请输入搜索关键词(支持姓名或电话的模糊匹配): ").trim();
|
||
|
||
if (keyword.isEmpty()) {
|
||
System.out.println("⚠ 搜索关键词不能为空!");
|
||
return;
|
||
}
|
||
|
||
List<Contact> results = new ArrayList<>();
|
||
for (Contact c : contacts.values()) {
|
||
if (c.name.contains(keyword) || c.phone.contains(keyword)) {
|
||
results.add(c);
|
||
}
|
||
}
|
||
|
||
if (results.isEmpty()) {
|
||
System.out.println("未找到匹配的联系人。");
|
||
} else {
|
||
System.out.println("\n找到 " + results.size() + " 条记录:");
|
||
for (Contact c : results) {
|
||
System.out.println(c);
|
||
}
|
||
}
|
||
}
|
||
|
||
/** 4. 修改联系人 */
|
||
static void updateContact() {
|
||
System.out.println("\n--- 修改联系人 ---");
|
||
String name = readInput("请输入要修改的联系人姓名: ").trim();
|
||
|
||
Contact target = contacts.get(name);
|
||
if (target == null) {
|
||
System.out.println("⚠ 未找到联系人 [" + name + "]。");
|
||
return;
|
||
}
|
||
|
||
System.out.println("当前信息:" + target);
|
||
System.out.println("(直接回车保留原值,输入新值则更新)");
|
||
|
||
String newPhone = readInput("新电话 [" + target.phone + "]: ");
|
||
if (!newPhone.trim().isEmpty()) {
|
||
target.setPhone(newPhone);
|
||
}
|
||
|
||
String newEmail = readInput("新邮箱 [" + target.email + "]: ");
|
||
if (!newEmail.trim().isEmpty()) {
|
||
target.setEmail(newEmail);
|
||
}
|
||
|
||
String newAddress = readInput("新地址 [" + target.address + "]: ");
|
||
if (!newAddress.trim().isEmpty()) {
|
||
target.setAddress(newAddress);
|
||
}
|
||
|
||
System.out.println("✅ 联系人 [" + name + "] 已更新!");
|
||
}
|
||
|
||
/** 5. 删除联系人 */
|
||
static void deleteContact() {
|
||
System.out.println("\n--- 删除联系人 ---");
|
||
String name = readInput("请输入要删除的联系人姓名: ").trim();
|
||
|
||
if (!contacts.containsKey(name)) {
|
||
System.out.println("⚠ 未找到联系人 [" + name + "]。");
|
||
return;
|
||
}
|
||
|
||
// 二次确认
|
||
System.out.print("确认删除 [" + name + "]?(y/n): ");
|
||
String confirm = scanner.nextLine().trim().toLowerCase();
|
||
|
||
if ("y".equals(confirm) || "yes".equals(confirm)) {
|
||
contacts.remove(name);
|
||
System.out.println("✅ 联系人 [" + name + "] 已删除!");
|
||
} else {
|
||
System.out.println("已取消删除。");
|
||
}
|
||
}
|
||
|
||
// ==================== 工具方法 ====================
|
||
|
||
/** 打印提示并读取一行输入 */
|
||
static String readInput(String prompt) {
|
||
System.out.print(prompt);
|
||
return scanner.nextLine();
|
||
}
|
||
|
||
/** 预置示例数据 */
|
||
static void initSampleData() {
|
||
contacts.put("张三", new Contact("张三", "13800138001", "zhangsan@mail.com", "北京市朝阳区"));
|
||
contacts.put("李四", new Contact("李四", "13900139002", "lisi@mail.com", "上海市浦东新区"));
|
||
contacts.put("王五", new Contact("王五", "13700137003", "wangwu@mail.com", "广州市天河区"));
|
||
}
|
||
}
|
||
|
||
// ==================== Contact 实体类 ====================
|
||
|
||
class Contact {
|
||
String name;
|
||
String phone;
|
||
String email;
|
||
String address;
|
||
|
||
public Contact(String name, String phone, String email, String address) {
|
||
this.name = name;
|
||
this.phone = phone;
|
||
this.email = email;
|
||
this.address = address;
|
||
}
|
||
|
||
// Getter / Setter(体现封装)
|
||
public String getName() { return name; }
|
||
public String getPhone() { return phone; }
|
||
public void setPhone(String phone) { this.phone = phone; }
|
||
public String getEmail() { return email; }
|
||
public void setEmail(String email) { this.email = email; }
|
||
public String getAddress() { return address; }
|
||
public void setAddress(String address) { this.address = address; }
|
||
|
||
@Override
|
||
public String toString() {
|
||
return String.format("[%s] 电话:%s 邮箱:%s 地址:%s", name, phone, email, address);
|
||
}
|
||
}
|