文章目录
- 一,项目要求
- 二,导入jar包 pinyin4j.jar
- 三,程序报下建立Pinyin4j类
- 四,创建实体类Contact
- 五,创建通讯录接口ContactDao
- 六,创建ContactDao接口的视线子类ContactDaoImpl
- 6.1 创建全局的Map对象和Scanner对象
- 6.2 插入至map的add方法
- 6.3 初始化方法init
- 6.4 实现方法 ui 菜单
- 6.5 实现方法 addContact 添加联系人信息
- 6.6 实现方法 showAllContacts 查看所有联系人信息
- 6.7 实现方法 showContactsByGroupName 通过分组查询联系人
- 6.8 实现方法 showContactsByName 通过姓名关键字查询联系人
- 6.9 实现方法 showContactsByPhone 通过电话关键字查询联系人
- 6.10 实现方法 modifyContact 修改联系人信息
- 6.11 实现方法 delectContactByName 删除联系人信息
- 6.12 实现方法 showContactsByKeyword 通过关键字(姓名或电话)查询联系人
- 七,测试
一,项目要求
通讯录项目要实现:菜单打印,添加联系人,查看全部联系人,根据分组查看联系人,根据姓名关键字
查看联系人,根据电话关键字查看联系人,修改联系人,删除联系人,退出等。
基础功能
(1) 通过Idea创建一个名为contact的包,在包里创建一个联系人类Contact,包含姓名name,手机号码
phone,分组groupName属性,包含一个构造方法public Contact(String name, String phone),在构
造方法里通过name计算groupName的值,name的setter方法中也要根据name重新给groupName赋
值。
通过汉字转拼音工具类计算分组名称。
(2) 在包里创建一个通讯录接口ContactDao。此接口中提供通讯录相关的各种核心功能抽象方法:
页面方法 public void ui();
添加联系人public void addContact();
查看全部联系人 public void showAllContacts();
根据分组查看联系人 public void showContactsByGroupName();
根据姓名关键字查看联系人 public void showContactsByName();
根据手机号关键字查看联系人 public void showContactsByPhone();
修改联系人public void modifyContact();
删除联系人 public void deleteContactByName();
(3) 在包里创建一个通讯录实现子类ContactDaoImpl,定义一个全局的Map存储所有联系人(TreeMap最
合适,key是分组名, value是List< Contact >)。实现通讯录相关的各种核心功能:
(4) 在包里创建一个ContactTest类,在类的main方法里调用测试
拓展
- 在项目已有功能的基础上,添加如下功能:
(1) 通讯录初始化时就包含5个人(自己以及自己的前后左右)。
有如下几种方式:
(1) 在AddressBook的构造方法中往Map中添加联系人
(2) 在初始化代码块里往Map中添加联系人。
(3) 自己写一个初始化方法public void init(); 在init方法中往Map里添加联系人, 然后在构造方
法里调用init方法。
(2) 给通讯录AddressBook类增加一个根据关键字查询联系人的功能public void
showContactsByKeyword(String keyword),关键字既可以是姓名关键字也可以是手机号关键字
二,导入jar包 pinyin4j.jar
在项目目录下建立一个lib包,再将已经下载好的pinyin4j.jar包导入其中
(该工具包用以获取联系人首字母)
三,程序报下建立Pinyin4j类
package synthesisHomework.contact;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
/**
* 汉字转换成拼音方法
*
* @author 蔡龙
*/
public class Pinyin4j {
HanyuPinyinOutputFormat format = null;
public static enum Type {
UPPERCASE, //全部大写
LOWERCASE, //全部小写
FIRSTUPPER //首字母大写
}
public Pinyin4j() {
format = new HanyuPinyinOutputFormat();
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
format.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
}
/**
* 转换全部大写
*
* @param str 字符串
* @return str为颐和园 ,return获取到的是YHY
* @throws BadHanyuPinyinOutputFormatCombination
*/
public String toPinYinUppercase(String str) throws BadHanyuPinyinOutputFormatCombination {
return toPinYin(str, "", Type.UPPERCASE);
}
/**
* 转换全部大写
*
* @param str 字符串
* @param spera 转换字母间隔加的字符串,如果不需要为""
* @return str为颐和园 ,spera为** return获取到的是Y**H**Y
* @throws BadHanyuPinyinOutputFormatCombination
*/
public String toPinYinUppercase(String str, String spera) throws BadHanyuPinyinOutputFormatCombination {
return toPinYin(str, spera, Type.UPPERCASE);
}
/**
* 转换全部小写
*
* @param str 字符串
* @throws BadHanyuPinyinOutputFormatCombination
* @return str为颐和园 ,return获取到的是yhy
*/
public String toPinYinLowercase(String str) throws BadHanyuPinyinOutputFormatCombination {
return toPinYin(str, "", Type.LOWERCASE);
}
/**
* 转换全部小写
*
* @param str 字符串
* @param spera 转换字母间隔加的字符串,如果不需要为""
* @throws BadHanyuPinyinOutputFormatCombination
* @return str为颐和园 ,spera为** return获取到的是y**h**y
*/
public String toPinYinLowercase(String str, String spera) throws BadHanyuPinyinOutputFormatCombination {
return toPinYin(str, spera, Type.LOWERCASE);
}
/**
* 获取拼音首字母(大写)
*
* @param str 字符串
* @return str为颐和园 ,return获取到的是Y
* @throws BadHanyuPinyinOutputFormatCombination 异常信息
*/
public String toPinYinUppercaseInitials(String str) throws BadHanyuPinyinOutputFormatCombination {
String initials = null;
String py = toPinYinUppercase(str);
if (py.length() > 1) {
initials = py.substring(0, 1);
}
if (py.length() <= 1) {
initials = py;
}
return initials.trim();
}
/**
* 获取拼音首字母(小写)
*
* @param str 字符串
* @return str为颐和园 ,return获取到的是y
* @throws BadHanyuPinyinOutputFormatCombination 异常信息
*/
public String toPinYinLowercaseInitials(String str) throws BadHanyuPinyinOutputFormatCombination {
String initials = null;
String py = toPinYinLowercase(str);
if (py.length() > 1) {
initials = py.substring(0, 1);
}
if (py.length() <= 1) {
initials = py;
}
return initials.trim();
}
/**
* 将str转换成拼音,如果不是汉字或者没有对应的拼音,则不作转换
*
* @param str 字符串
* @param spera 默认,可为""
* @param type 转换格式
* @return 按照转换格式转换成字符串
* @throws BadHanyuPinyinOutputFormatCombination 异常信息
*/
public String toPinYin(String str, String spera, Type type) throws BadHanyuPinyinOutputFormatCombination {
if (str == null || str.trim().length() == 0) {
return "";
}
if (type == Type.UPPERCASE) {
format.setCaseType(HanyuPinyinCaseType.UPPERCASE);
} else {
format.setCaseType(HanyuPinyinCaseType.LOWERCASE);
}
String py = "";
String temp = "";
String[] t;
for (int i = 0; i < str.length(); i++) {
char c = str.charAt(i);
if ((int) c <= 128) {
py += c;
} else {
t = PinyinHelper.toHanyuPinyinStringArray(c, format);
if (t == null) {
py += c;
} else {
temp = t[0];
if (type == Type.FIRSTUPPER) {
temp = t[0].toUpperCase().charAt(0) + temp.substring(1);
}
if (temp.length() >= 1) {
temp = temp.substring(0, 1);
}
py += temp + (i == str.length() - 1 ? "" : spera);
}
}
}
return py.trim();
}
}
四,创建实体类Contact
题目中有一项要求是在构造器时通过name的值获取groupName的值
在这里使用到了Pinyin4j类中的方法
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public class Contact {
private String name;
private String phone;
private String groupName;
public Contact() {
}
@Override
public String toString() {
return name+"("+phone+")" ;
}
public Contact(String name, String phone) throws BadHanyuPinyinOutputFormatCombination {
this.name = name;
this.phone = phone;
// 使用pinyin4j获取姓名首字母
this.groupName = new Pinyin4j().toPinYinUppercaseInitials(this.name);
}
public String getName() {
return name;
}
public void setName(String name) throws BadHanyuPinyinOutputFormatCombination {
this.name = name;
this.groupName = new Pinyin4j().toPinYinLowercaseInitials(this.name);
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getGroupName() {
return groupName;
}
}
五,创建通讯录接口ContactDao
创建通讯录接口以规范其中用到的方法名
package synthesisHomework.contact;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;
public interface ContactDao {
// 页面方法
void ui() throws BadHanyuPinyinOutputFormatCombination;
// 添加联系人
void addContact() throws BadHanyuPinyinOutputFormatCombination;
// 查看全部联系人
void showAllContacts();
// 根据分组查看联系人
void showContactsByGroupName();
// 根据姓名关键字查看联系人
void showContactsByName();
// 根据手机号关键字查看联系人
void showContactsByPhone();
// 修改联系人
void modifyContact() throws BadHanyuPinyinOutputFormatCombination;
// 删除联系人
void deleteContactByName();
}
六,创建ContactDao接口的视线子类ContactDaoImpl
创建ContactDaoImpl类实现接口中的抽象方法
6.1 创建全局的Map对象和Scanner对象
Map<String, List<Contact>> map = new TreeMap<String, List<Contact>>();
Scanner sc = new Scanner(System.in);
6.2 插入至map的add方法
public void add(String name,String phone) throws BadHanyuPinyinOutputFormatCombination {
Contact contact = new Contact(name,phone);
// 如果没有分组则创建一个分组,并为该分组new一个ArrayList
if(!map.containsKey(contact.getGroupName()))
map.put(contact.getGroupName(),new ArrayList<Contact>());
// 根据对应的key值加入输入的信息
map.get(contact.getGroupName()).add(contact);
}
6.3 初始化方法init
调用add方法将初始化信息加入到map中
public void init() throws BadHanyuPinyinOutputFormatCombination {
add("小孤鸡","15577776666");
add("大孤鸡","17788889966");
add("中孤鸡","14728742783");
add("黑孤鸡","18222778866");
add("白孤鸡","19233337777");
}
6.4 实现方法 ui 菜单
1.在进入菜单时优先调用init方法对通讯录进行初始化
2.再使用while无限循环进行菜单的输出
3.从控制台输入值并通过switch语句进行判断并跳转至对应的操作
@Override
public void ui() throws BadHanyuPinyinOutputFormatCombination {
// 初始放置五个数据
init();
while(true){
System.out.println("=======通讯录=======\n" +
"1.添加联系人\n" +
"2.查看全部联系人\n" +
"3.根据分组查看联系人\n" +
"4.根据姓名关键字查看联系人\n" +
"5.根据电话关键字查看联系人\n" +
"6.修改联系人\n" +
"7.删除联系人\n" +
"8.关键字查询(姓名或电话)\n" +
"9.退出\n" +
"请输入您的选择(1-8): ");
String n = sc.next();
switch(n){
case "1":addContact();break;
case "2":showAllContacts();break;
case "3":showContactsByGroupName();break;
case "4":showContactsByName();break;
case "5":showContactsByPhone();break;
case "6":modifyContact();break;
case "7":deleteContactByName();break;
case "8":showContactsByKeyword();break;
case "9":System.out.println("退出系统!");return;
default:
System.out.println("输入错误,请重新输入");break;
}
}
}
6.5 实现方法 addContact 添加联系人信息
1.使用while循环对姓名和电话进行录入
2.通过判断是否符合规定的正则表达式来跳出while循环(即判断姓名和电话是否合法)
3.将name和phone作为参数调用add方法,将信息插入到map中
@Override
public void addContact() throws BadHanyuPinyinOutputFormatCombination {
String name;
String phone;
// 判断联系人姓名是否符合规范
while(true){
System.out.println("请输入联系人姓名:");
name = sc.next();
if (!name.matches("^[\u4e00-\u9f5a]+$")) {
System.out.println("姓名不合法,请重新输入");
continue;
}
break;
}
// 判断联系人电话是否符合规范
while(true){
System.out.println("请输入联系人电话:");
phone = sc.next();
if (!phone.matches("^(13|14|15|17|18|19)\\d{9}$")) {
System.out.println("电话号码不合法,请重新输入");
continue;
}
break;
}
add(name,phone);
// 添加成功
System.out.println("添加成功!!!");
}
6.6 实现方法 showAllContacts 查看所有联系人信息
1.判断是否为空
2.使用entrySet方法获取键值对并遍历输出所有信息
@Override
public void showAllContacts() {
// entrySet方法获取键值对遍历输出
if(map.isEmpty()) {
System.out.println("还没有联系人哦!");
}
else {
for (Map.Entry<String, List<Contact>> entry : map.entrySet()) {
System.out.println(entry.getKey());
for (Contact contact : entry.getValue()) {
System.out.println(contact);
}
}
}
}
6.7 实现方法 showContactsByGroupName 通过分组查询联系人
1.输入要查询的分组,并用正则表达式判断输入是否有误
2.将字符转为大写(在创建groupName时将首字母设为了大写)
3.通过map的get方法对比输入的分组信息
4.输出分组无联系人或者遍历输出所有该分组的联系人
@Override
public void showContactsByGroupName() {
System.out.println("请输入你要查询的分组:(a-z)");
String c = "";
while(true){
c = sc.next();
if(c.matches("^[A-Z|a-z]{1}$"))
break;
else System.out.println("只能输入一个字母哦!");
}
c=c.toUpperCase();
// 通过map的get方法对比输入的分组信息
Collection<Contact> contacts = map.get(c);
// 如果不存在这个分组则直接return
if(contacts == null) {
System.out.println(c + "分组尚无联系人");
return;
}
// 遍历输出分组对应的信息
for(Contact contact : contacts){
System.out.println(contact);
}
}
6.8 实现方法 showContactsByName 通过姓名关键字查询联系人
1.输入姓名关键字
2.用Collection 接收map中的values
3.设置计数器,因为找到的人可能不止一个
4.遍历values,通过contains方法比对关键字找出对应的信息并输出,计数器加一
@Override
public void showContactsByName() {
System.out.println("请输入姓名关键字:");
String name = sc.next();
// 用Collection 中的获取map中的值
Collection<List<Contact>> values = map.values();
// 计数,因为找到的人可能不止一个
int count=0;
// 遍历values,找到对应的信息
for(List<Contact> list : values){
for(Contact contact : list){
if(contact.getName().contains(name)){
System.out.println(contact);count++;
}
}
}
// 如果一个也没有找到,输出提示信息
if(count == 0){
System.out.println("没有找到符合的联系人");
}
}
6.9 实现方法 showContactsByPhone 通过电话关键字查询联系人
类似于6.8
@Override
public void showContactsByPhone() {
System.out.println("输入电话关键字:");
String phone = sc.next();
// 用Collection 中的获取map中的值
Collection<List<Contact>> values = map.values();
// 计数,因为找到的人可能不止一个
int count=0;
// 遍历values,找到对应的信息
for(List<Contact> list : values){
for(Contact contact : list){
if(contact.getPhone().contains(phone)){
System.out.println(contact);count++;
}
}
}
// 如果一个也没有找到,输出提示信息
if(count == 0){
System.out.println("没有找到符合的联系人");
}
}
6.10 实现方法 modifyContact 修改联系人信息
1.输入联系人全名
2.通过map中values方法遍历所有联系人信息
3.如果找到对应信息,预览并调用addContact方法进行新信息的插入
4.删除旧的信息,如果删除后,对应的组别内容为空,则将分组信息也删除
@Override
public void modifyContact() throws BadHanyuPinyinOutputFormatCombination {
System.out.println("请输入要修改的联系人的全名:");
String name = sc.next();
Collection<List<Contact>> values = map.values();
for(List<Contact> list : values){
for(Contact contact : list){
if(contact.getName().equals(name)){
System.out.println("联系人信息:"+contact);
addContact();
// 先删除被修改过的信息
list.remove(contact);
// 再判断组别是否为空,为空的话删除组别信息
if(list.isEmpty())map.remove(contact.getGroupName());
System.out.println("修改成功");return;
}
}
}
System.out.println("要修改的联系人不存在");
}
6.11 实现方法 delectContactByName 删除联系人信息
1.输入姓名全名
2.values遍历预览信息
3.判断是否确定删除
4.如果删除后组内为空,则删除分组
@Override
public void deleteContactByName() {
System.out.println("请输入要删除的联系人的姓名:");
String name = sc.next();
Collection<List<Contact>> values = map.values();
for(List<Contact> list : values){
for(Contact contact : list){
if(contact.getName().equals(name)){
// 预览找到的联系人信息
System.out.println("联系人信息:"+contact);
// 是否删除
System.out.println("是否确定删除(Y/N)");
if(sc.next().equalsIgnoreCase("y")){
list.remove(contact);
}else return;
// 再判断组别信息是否为空,为空的话删除分组名
if(list.isEmpty())map.remove(contact.getGroupName());
System.out.println("删除成功");return;
}
}
}
}
6.12 实现方法 showContactsByKeyword 通过关键字(姓名或电话)查询联系人
1.输入关键字,定义计数器
2.遍历并比对关键字(姓名或电话),找到了则count++
3.判断计数器是否为0
public void showContactsByKeyword(){
System.out.println("请输入关键字:");
String keyword = sc.next();
int count=0;
Set<Map.Entry<String, List<Contact>>> entrys = map.entrySet();
for(Map.Entry<String, List<Contact>> entry : entrys){
for(Contact contact : entry.getValue()){
if(contact.getName().contains(keyword)||contact.getPhone().contains(keyword)){
System.out.println(contact);
count++;
}
}
}
if(count == 0)
System.out.println("没找到该联系人");
}
七,测试
7.1 初始化通讯录
7.2 添加联系人
7.3 根据分组查询联系人
7.4 根据姓名关键字查询联系人
7.5 根据电话关键字查询联系人
7.6 修改联系人
7.7 删除联系人
7.8 关键字查询 (姓名或电话)