通讯录-Java
目录
文章目录
内容
1、需求
现需要开发一个通讯录功能,具体功能如下:
- A:显示所有联系人
- B:查找某一位联系人
- C:添加联系人
- D:删除联系人
- E:修改联系人
- F:结束当前所有操作
2、界面功能
- 刚进入cmd里面的主界面 -》 6个小模块
- A:显示所有联系人
- B:查找某一位联系人
- C:添加联系人
- D:删除联系人
- E:修改联系人
- F:结束当前所有操作
3、联系人
-
手机通讯录联系人分类:
- 亲人:relative
- 同事: colleague
- 朋友: friend
- 其他: other
-
手机通讯录里面所有的联系人底层都装进一个集合对象里面 -》 ArrayList
-
亲人 同事 朋友 其他类型里面共有的属性:
- char initial;->首字母
- String name->联系人名字
- int age->联系人年龄
- char gender->联系人性
- long phone->手机号码
- String zuoJi->座机号码 = 区号 + 号码
- 举例: 0531-6661760
- 区号
- 0564: 六安
- 0531:济南
- 0532:青岛
- 号码:7位数字
-
创建联系人对象的时候:
- szm name age gender phone是必填内容
- zuoJi可填可不填
-
座机
- 如果创建联系人对象的时候 用户如果没有提供zuoJi属性值 ,那么将zuoJi变量直接赋值为"无座机号码"
- 如果创建联系人对象的时候 用户如果提供zuoJi属性值了 ,那么直接将zuoJi变量赋值为用户输入的值
-
所有类里面的属性要求封装
4、测试数据
朋友 x1 = new 朋友('Z',"张三",22,'男',15555555555L,"0531-6661760");
朋友 x2 = new 朋友('X',"小明",18,'男',18756789000L);
亲人 x3 = new 亲人('W',"王刚美",28,'女',18322009876L);
同事 x4 = new 同事('A',"阿磊",24,'男',15559501427L,"0564-6021117");
亲人 x5 = new 亲人('Z',"周凯",38,'男',18765432189L);
朋友 x6 = new 朋友('Z',"周s人",99,'男',17499990427L);
朋友 x7 = new 朋友('Z',"张三",22,'男',15555445555L);
//一个模块一个模块写 写完测试 测试通过写下一个模块
5、具体功能需要和实现
5.1、显示所有联系人
如果用户选择是A 那么有两种选择:
-
输入校验:
用户可能输进去的不是a/b 要求重新输入
再次输入的内容也需要校验
直到用户输入一个正确的内容-
a:按照首字母进行显示分类:
[效果如下:]A 阿磊 1555950427 W 王刚美 18322009876 X 小明 18756789000 Z 张三 15555555555 周凯 18765432189 ....
-
b:按照类别进行分类显示:
[效果如下:]朋友 张三 15555555555 小明 18756789000 周s人 17499990427 张三 15555445555 亲人 王刚美 18322009876 周凯 18765432189 同事 阿磊 1555950427 ...
-
5.2、查找某一位联系人
如果用户选择的是B:,cmd面板显示下面这句话:
请问你是通过联系人名字进行精确查找/手机号码模糊查询
这里用户有两种选择:
-
用户可以直接的输入要查找联系人的名字
-
如果集合里面没有该用户 直接显示:
不好意思 当前用户不存在 -
如果集合里面有该用户 需要将用户的基本信息进行展示:
[效果如下:] [输入]张三 [显示] 用户的基本信息: 联系人姓名:张三 联系人电话:15555555555 联系人座机号码:0531-6661760 座机显示城市:济南 用户的基本信息: 联系人姓名:张三 联系人电话:15555445555 联系人座机号码:无座机号码 座机显示城市:未知城市
-
-
用户还可以直接输入一段电话号码-》出现几个数字就可以
-
如果集合里面没有用户的号码出现这几个数字的 直接显示:
不好意思 当前用户不存在
-
如果查找到有这个用户存在 显示下面:
[效果如下:] [输入]555555 [显示] 用户的基本信息: 联系人姓名:张三 联系人电话:15555555555 联系人座机号码:0531-6661760 座机显示城市:济南
-
5.3、添加联系人
如果用户选择的是C:
-
需要进行输入校验:
- 选择的分类可能不是亲人 朋友 同事 默认其他
- 输入的大写首字母可能不是大写首字母 是数字 是其他的汉字
- 注册用户名字的时候 应国家要求 关键字需要屏蔽(不能是敏感字…)
- 输入的年龄非数字
- 性别选择的不是A/B
- 输入电话号码的时候 非11为数字 不是数字 不是以138 130 137 158 155 188. .开头
- 座机可能不是按照 区号-号码的形式传进去的
- 座机号码的区号只能出现0564 0531 0532
-
cmd里面直接出现下面的内容:
请选择联系人的分类A:亲人 B:同事 C:朋友 D:其他 请输入联系人名字大写首字母: 请输入联系人的姓名: 请输入联系人的年龄: 请选择联系人性别:A:男 B:女 请输入联系人的电话: 请输入联系人座机号码(没有请回复N):N/区号-座机号
-
当用户依次输入所有的信息之后 产生一个联系人,但是需要判断集合里面是否已经存在该用户
-
如果存在(只要手机号码相同就认为是同一个联系人) ,那么就不能继续添加进通讯录里面
cmd里面显示:对不起 当前用户已经存在 同一个用户不能添加多次
-
如果不存在 将当前联系人添加进集合里面
cmd里面显示:添加成功
-
5.4、删除联系人
如果用户选择的是D:
-
直接在cmd里面先以表的形式将所有联系人的信息显示出来:
[效果如下:] 编号 姓名 年龄 电话 0 张三 22 155****5555 1 小明 18 187****9000 2 王刚美 28 183****9876 3 阿磊 24 155****4278 4 周凯 38 187****2189 5 周s人 99 174****0427 cmd里面显示:请问你要删除联系人的编号:
-
输入校验:
-
需要对当前输入的编码进行判断 是不是数字
- 如果不是 需要重新输入(从新输进去的内容还是需要进行输入校验),直到用户输入一个合法的数字
-
如果集合里面有该编码对象的元素 ,从集合里面将当前编号的联系人删除 并在cmd里面显示删除成功
-
如果集合里面没有该编号对应的联系人
cmd里面显示:对不起 没有该编码对应的联系人
-
5.5、修改联系人
如果用户选择的是E:
-
输入校验
-
修改之后的姓名还是不能出现关键字
-
修改之后的电话号码还是只能以155 159…开头
-
修改后的大写首字母还是要判断是否合法
-
可能用户不是按照格式正确输入 XXX-XXX-XXX(无论是修改前的输入还是修改后的输入格式需要正确)
[效果如下] 请输入你要修改联系人的姓名大写首字母 姓名 联系电话(中间-隔开):Z-张三-15555555555
-
-
找到集合里面对应的联系人
-
如果集合里面没有该对象显示:不好意思 当前联系人不存在
-
如果找到要修改的联系人 显示一下提示语:
请输入修改后的联系人的姓名大写首字母 姓名 联系电话(中间-隔开):L-李四-18900000000
-
-
修改结束显示修改成功
5.6、结束当前所有操作
如果用户选择的是F:
直接结束当前所有的操作 -》 break
6、完整代码
-
联系人父类Contact代码6-1:
package addressBook; /** * 联系人 * @author Administrator * */ public abstract class Contact { private char initial; // 首字母-修改 private String name; private int age; private char gender; private long phone; private String zuoji; // 座机-修改 public Contact() {} public Contact(char initial, String name, int age, char gender, long phone) { super(); this.initial = initial; this.name = name; this.age = age; this.gender = gender; this.phone = phone; } public Contact(char initial, String name, int age, char gender, long phone, String zuoji) { super(); this.initial = initial; this.name = name; this.age = age; this.gender = gender; this.phone = phone; this.zuoji = zuoji; } public char getInitial() { return initial; } public void setInitial(char initial) { this.initial = initial; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public char getGender() { return gender; } public void setGender(char gender) { this.gender = gender; } public long getPhone() { return phone; } public void setPhone(long phone) { this.phone = phone; } public String getZuoji() { return zuoji; } public void setZuoji(String zuoji) { this.zuoji = zuoji; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Contact other = (Contact) obj; if (phone != other.phone) return false; return true; } @Override public String toString() { return this.name + "\t" + this.phone; } }
-
亲人Relative代码6-2:
package addressBook; public class Relative extends Contact { public Relative() { super(); // TODO Auto-generated constructor stub } public Relative(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); // TODO Auto-generated constructor stub } public Relative(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); // TODO Auto-generated constructor stub } }
-
朋友Friend代码6-3:
package addressBook; public class Friend extends Contact{ public Friend() {} public Friend(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); } public Friend(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); } }
-
同事Colleague代码6-4:
package addressBook; public class Colleague extends Contact { public Colleague() { super(); // TODO Auto-generated constructor stub } public Colleague(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); // TODO Auto-generated constructor stub } public Colleague(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); // TODO Auto-generated constructor stub } }
-
其他类Other代码6-5:
package addressBook; public class Other extends Contact { public Other() { super(); // TODO Auto-generated constructor stub } public Other(char initial, String name, int age, char gender, long phone, String zuoji) { super(initial, name, age, gender, phone, zuoji); // TODO Auto-generated constructor stub } public Other(char initial, String name, int age, char gender, long phone) { super(initial, name, age, gender, phone); // TODO Auto-generated constructor stub } }
-
通讯录AddressBook类代码6-6:
package addressBook; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Scanner; import java.util.TreeSet; import java.util.stream.Stream; /** * 通讯录 * @author Administrator * */ public class AddressBook { private List<Contact> list; private Map<String, String> cities; private Scanner sc; private String errMsg = "输入有误!"; private static final int VERIFY_RANGE = 1; private static final int VERIFY_INITIAL = 2; private static final int VERIFY_NAME = 3; private static final int VERIFY_AGE = 4; private static final int VERIFY_PHONE = 5; private static final int VERIFY_ZUOJI = 6; private static final int VERIFY_NO = 7; public AddressBook() { list = new ArrayList<>(); } public AddressBook(List<Contact> list, Scanner sc, Map<String, String> cities) { this.list = list; this.sc = sc; this.cities = cities; } /** * 显示所有联系人 */ public void showInfo() { this.printSeparatorLine("进入显示所有联系人模块"); String notice = "请输入显示方式:a(首字母)/b(类别)/c(索引表格)"; System.out.println(notice); String[] range = {"a", "b", "c"}; String type = this.ensureInput(this.errMsg + notice, range); if (type.trim().equalsIgnoreCase("a")) //a:按照首字母进行显示分类: this.showInitial(); else if(type.trim().equalsIgnoreCase("b")) //b:按照类别进行分类显示: this.showCategory(); // c:打印带索引的表格数据 else this.printAll(); this.printSeparatorLine("离开显示所有联系人模块"); } /** * 按首字母显示 */ public void showInitial() { TreeSet<Character> shouzimu = new TreeSet<>(); list.stream().forEach(n -> shouzimu.add(n.getInitial())); shouzimu.stream().forEach(s -> { System.out.println(s); list.stream().filter(x -> (x.getInitial() == s)).forEach(System.out::println); System.out.println(); }); } /** * 按类别显示 */ public void showCategory() { System.out.println("\t朋友"); list.stream().filter(x -> (x instanceof Friend)).forEach(System.out::println); System.out.println(); System.out.println("\t亲人"); list.stream().filter(x -> (x instanceof Relative)).forEach(System.out::println); System.out.println(); System.out.println("\t同事"); list.stream().filter(x -> (x instanceof Colleague)).forEach(System.out::println); System.out.println(); System.out.println("\t其他"); list.stream().filter(x -> (x instanceof Other)).forEach(System.out::println); System.out.println(); } /** * 打印分割线 */ public void printSeparatorLine(String str) { System.out.println("-----" + str + "-----"); } /** * 查找某个联系人模块 */ public void find() { this.printSeparatorLine("进入查找联系人模块"); String notice = "请输入查找方式:a(联系人名字进行精确查找)/b(手机号码模糊查询)"; System.out.println(notice); String[] range = {"a", "b"}; String type = this.ensureInput(this.errMsg + notice, range); System.out.println("请输入:"); String info = sc.nextLine(); Contact[] c = (type.trim().equalsIgnoreCase("a"))? this.findByName(info) : this.findByPhone(info); if(c.length == 0) System.out.println("不好意思当前用户不存在"); else Stream.of(c).forEach(this::printOneInfo); this.printSeparatorLine("离开查找联系人模块"); } /** * 通过人名查找 * @param name * @return */ public Contact[] findByName(String name) { return (this.list.stream().filter(s -> s.getName().equals(name)).toArray(Contact[]::new)); } /** * 通过手机号查找 * @param phone * @return */ public Contact[] findByPhone(String phone) { return (this.list.stream().filter(s -> ("" + s.getPhone()).contains(phone)).toArray(Contact[]::new)); } /** * 格式打印个人信息 * @param c */ public void printOneInfo(Contact c) { StringBuffer sb = new StringBuffer(); String zuoji = Objects.nonNull(c.getZuoji())? c.getZuoji(): "无座机号码"; String city = Objects.nonNull(c.getZuoji())? this.cities.get(c.getZuoji().split("-")[0]): "未知城市"; sb.append("用户的基本信息:\r\n") .append("联系人姓名:").append(c.getName()).append("\r\n") .append("联系人电话:").append(c.getPhone()).append("\r\n") .append("联系人座机号码:").append(zuoji).append("\r\n") .append("座机显示城市:").append(city).append("\r\n"); System.out.println(sb); } /** * 添加联系人模块 */ public void addContact() { this.printSeparatorLine("进入添加联系人模块"); // 创建联系人对象 Contact c = null; System.out.println("请选择联系人的分类A:亲人 B:同事 C:朋友 D:其他 "); String category = sc.nextLine(); switch(category) { case "亲人": c = new Relative(); break; case "同事": c = new Colleague(); break; case "朋友": c = new Friend(); break; default: c = new Other(); } // 设置联系人属性 // 设置首字母; String notice = "请输入联系人名字大写首字母:"; System.out.println(notice); String str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_INITIAL); c.setInitial(str.charAt(0)); // 设置姓名 notice = "请输入联系人姓名:"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_NAME); c.setName(str); // 设置年龄: notice = "请输入联系人的年龄:"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_AGE); c.setAge(Integer.parseInt(str)); // 设置性别 notice = "请选择联系人性别:A:男 B:女"; System.out.println(notice); String[] range = {"a", "b"}; str = this.ensureInput(this.errMsg + notice, range); c.setGender(str.trim().equalsIgnoreCase("a")? '男': '女'); // 设置联系人电话 notice = "请输入联系人的电话:"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_PHONE); c.setPhone(Long.parseLong(str)); // 设置座机号码 notice = "请输入联系人座机号码(没有请回复N):N/区号-座机号"; System.out.println(notice); str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_ZUOJI); if(!str.equalsIgnoreCase("N")) c.setZuoji(str); // 新添加的联系人加入集合 this.list.add(c); System.out.println("添加成功"); this.printSeparatorLine("离开添加联系人模块"); } /** * 删除联系人模块 */ public void deleteContact() { this.printSeparatorLine("删除联系人模块"); // 打印联系人列表 this.printAll(); String notice = "请问你要删除联系人的编号: "; System.out.println(notice); String str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_NO); this.list.remove(Integer.parseInt(str)); System.out.println("删除成功"); this.printSeparatorLine("离开删除联系人模块"); } /** * 表格打印 */ public void printAll() { System.out.println("编号\t姓名\t年龄\t电话"); for(int i = 0; i < this.list.size(); i++) { String str ="" + this.list.get(i).getPhone(); str = str.substring(0, 3) + "****" + str.substring(7); System.out.println(i + "\t" + this.list.get(i).getName() + "\t" + this.list.get(i).getAge() + "\t" + str); } } /** * 修改联系人模块 */ public void updateContact() { this.printSeparatorLine("修改联系人模块"); this.printAll(); String notice = "请问你要修改联系人的编号: "; System.out.println(notice); String str = this.ensureInput(this.errMsg + notice, AddressBook.VERIFY_NO); int no = Integer.parseInt(str); // 输入修改信息 String[] info = null; System.out.println("请输入你要修改联系人的姓名大写首字母-姓名-联系电话(中间-隔开): "); while(true) { str = sc.nextLine(); if(this.verifyUpdateInfo(str)) { info = str.split("-"); if(this.verifyInitial(info[0]) && this.verifyName(info[1]) && this.verifyPhone(info[2])) break; } System.out.println("输入有误!请输入你要修改联系人的姓名大写首字母 姓名 联系电话(中间-隔开): "); } this.list.get(no).setInitial(info[0].charAt(0)); this.list.get(no).setName(info[1]); this.list.get(no).setPhone(Long.parseLong(info[2])); System.out.println("修改成功"); this.printSeparatorLine("离开修改联系人模块"); } /** * 首字母校验 * @param str * @return */ public boolean verifyInitial(String str) { System.out.println("校验首字母"); return Objects.nonNull(str) && str.matches("^[A-Z]$"); } /** * 手机号码校验 * @param str * @return */ public boolean verifyPhone(String str) { System.out.println("校验手机号"); return Objects.nonNull(str) && str.matches("^1[358]\\d{9}$"); } /** * 校验姓名 * @param str * @return */ public boolean verifyName(String str) { System.out.println("校验姓名"); if(Objects.isNull(str)) return false; String keywords[] = {"SB", "2B", "BC"}; for(String n: keywords) { if(n.equals(str)) return false; } return true; } /** * 校验年龄 * @param str * @return */ public boolean verifyAge(String str) { return Objects.nonNull(str) && str.matches("^\\d+$") && Integer.parseInt(str) > 0 && Integer.parseInt(str) <= 200; } /** * 校验座机号码 * @param str * @return */ public boolean verifyZuoJi(String str) { return Objects.nonNull(str) && str.matches("^05[36][124]-\\d{7}$|N|n"); } /** * 校验编号 * @param str * @return */ public boolean verifyNo(String str) { return Objects.nonNull(str) && str.matches("^[0-9]+$") && Integer.parseInt(str) <= this.list.size() - 1; } /** * 修改联系人信息输入校验 * @param str * @return */ public boolean verifyUpdateInfo(String str) { System.out.println("校验输入信息"); return Objects.nonNull(str) && str.matches("^[A-Z]-.*-\\d+$"); } /** * 输入校验,确保输入内容在range数组内 * @param errorMsg 错误提升 * @param range 可输入范围数组 * @return */ public String ensureInput(String errorMsg, String... range) { String type = null; while(true) { type = this.sc.nextLine(); boolean flag = false; // 输入校验: // 用户可能输进去的不是range中内容, 要求重新输入 //再次输入的内容也需要校验 //直到用户输入一个正确的内容 for(String s: range) { if(s.equalsIgnoreCase(type)) { flag = true; break; } } if(flag) break; System.out.println(errorMsg); } return type; } public String ensureInput(String errorMsg, int verifyType) { String str = null; while(true) { str = sc.nextLine(); // if(str.matches("^[0-9]+$") && Integer.parseInt(str) <= this.list.size()) break; boolean flag = false; switch(verifyType) { case 2: if(this.verifyInitial(str)) flag = true; break; case 3: if(this.verifyName(str)) flag = true; break; case 4: if(this.verifyAge(str)) flag = true; break; case 5: if(this.verifyPhone(str)) flag = true; break; case 6: if(this.verifyZuoJi(str)) flag = true; break; default: } if(flag) break; System.out.println(errorMsg); } return str; } }
-
测试类TestAddressBook类:
package addressBook; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; public class TestAddressBook { public static void main(String[] args) { Friend x1 = new Friend('Z',"张三",22,'男',15555555555L,"0531-6661760"); Friend x2 = new Friend('X',"小明",18,'男',18756789000L); Relative x3 = new Relative('W',"王刚美",28,'女',18322009876L); Colleague x4 = new Colleague('A',"阿磊",24,'男',15559501427L,"0564-6021117"); Relative x5 = new Relative('Z',"周凯",38,'男',18765432189L); Friend x6 = new Friend('Z',"周树人",99,'男',17499990427L); Friend x7 = new Friend('Z',"张三",22,'男',15555445555L); Other x8 = new Other('L',"李四",22,'男',15555445558L); List<Contact> list = new ArrayList<>(); Collections.addAll(list, x1, x2, x3, x4, x5, x6, x7, x8); Scanner sc = new Scanner(System.in); Map<String, String> cities = new HashMap<>(); cities.put("0531", "济南"); cities.put("0532", "青岛"); cities.put("0564", "六安"); AddressBook t = new AddressBook(list, sc, cities); // 显示测试 // t.showInitial(); // t.showCategory(); // t.showInfo(); // 测试查找 // Contact[] c = t.findByName("张三"); // Contact[] c = t.findByPhone("5559"); // System.out.println(Arrays.toString(c)); // t.find(); // String str = "W-王五-13899999999"; // System.out.println(str.matches("^05[36][124]-\\d{7}$|N")); // t.addContact(); // t.printAll(); // t.deleteContact(); // t.printAll(); // System.out.println(str.matches("^[A-Z]-.*-\\d+$")); // t.updateContact(); // t.printAll(); System.out.println("-----欢迎进入通讯录----"); Scanner s = new Scanner(System.in); while(true) { System.out.println("-----功能界面-----"); System.out.println("A:显示所有联系人"); System.out.println("B:查找某一位联系人"); System.out.println("C:添加联系人"); System.out.println("D:删除联系人"); System.out.println("E:修改联系人"); System.out.println("F:结束当前所有操作"); System.out.println("-----功能界面-----"); System.out.println("请输入功能编号A-F:"); String str = s.nextLine(); boolean flag = false; switch(str.toLowerCase()) { case "a": t.showInfo(); break; case "b": t.find(); break; case "c": t.addContact(); break; case "d": t.deleteContact(); break; case "e": t.updateContact(); break; case "f": flag = true; break; default: } if(flag) break; } System.out.println("-----离开通讯录----"); } } 测试结果:自己测试,有bug记得通知我
后记 :
本项目为参考某马视频开发,相关视频及配套资料可自行度娘或者联系本人。上面为自己编写的开发文档,持续更新。欢迎交流,本人QQ:806797785
前端项目源代码地址:https://gitee.com/gaogzhen/vue-leyou
后端JAVA源代码地址:https://gitee.com/gaogzhen/JAVA