一项目内容
这个项目终于有点期末实训项目的复杂感了,当然也是比较基础的东西!不过我们的需求文档中做了各种奇怪的要求(这根本不是一个通讯录该有的功能啊喂!),也是为了全面的复习我们学过的基础知识。这个项目大概是400行的感觉!

上面就是我们要实现的功能!好像跟项目1没什么区别?主要还是各种要求让我们弄的很复杂,还是直接看代码吧!
二、代码
1、框架与Person类及其子类
这些是静态数据、主方法和选择框架。没错我的一贯编程习惯!主方法里面放最少的东西,尽量在其他地方实现我们的功能!
import java.math.*;
import java.util.*;
public class Project2_1{
static Scanner sc = new Scanner(System.in);
static Friend x1 = new Friend('J',"Jim",22,'B',15555555551L,"0531-88488697");
static Friend x2 = new Friend('R',"Ranor",22,'B',15555555552L);
static Colleague x3 = new Colleague('A',"Ava",22,'G',15555555553L,"0531-88488697");
static Colleague x4 = new Colleague('A',"Alex",22,'G',15555555554L);
static Colleague x5 = new Colleague('T',"Tom",22,'B',15555555555L);
static Colleague x6 = new Colleague('B',"Ben",22,'B',15555555556L);
static Relative x7 = new Relative('J',"Jhone",22,'G',15555555557L,"0564-88488697");
static Relative x8 = new Relative('H',"Henry",22,'B',15555555558L);
static Other x9 = new Other('L',"Luna",22,'G',15555555559L);
static ArrayList<Person> list = new ArrayList<>();
public static void main(String[] args){
select();
}
public static void select(){
Collections.addAll(list,x1,x2,x3,x4,x5,x6,x7,x8,x9);
while(true){
System.out.println("A:查看所有联系人\nB:查找某一位联系人\nC:添加联系人\nD:删除联系人\nE:修改联系人\nF:结束所有操作");
String ax = sc.next();
if(ax.equals("A")){OB();}
else if(ax.equals("B")){find();}
else if(ax.equals("C")){add();}
else if(ax.equals("D")){delete();}
else if(ax.equals("E")){modify();}
else if(ax.equals("F")){break;}
else { System.out.println("不要将奇怪的东西放到里面来啊喂!");}
}
}
}
下面是Person类的部分
呼,这个类可真多啊,Person类是一个父类,后面有其他的子类,除了封装的属性以及对封装的属性操作的方法以外,我们还有两个构造方法!这是因为我们的静态数据中,你可能也注意到了,有座机号码,这个有些人是没有的,因此我们要可选的进行对象创建,于是我们将构造方法进行重载处理。
然后是覆盖了equals();方法!!当时刚刚学覆盖equals,下意识直接覆盖了,后面好像根本没用到来着,覆盖equals是为了能让两个同类的对象进行比较,equals方法原先是用于String类型之间的比较的。
class Person{
private char szm;
private String name;
private int age;
private char gender;
private long phone;
private String z_phone;
public Person(char szm, String name, int age, char gender, long phone){
this.szm = szm;
this.name = name;
this.age = age;
this.gender = gender;
this.phone = phone;
this.z_phone = null;
}
public Person(char szm, String name, int age, char gender, long phone, String z_phone){
this.szm = szm;
this.age = age;
this.gender = gender;
this.name = name;
this.phone = phone;
this.z_phone = z_phone;
}
public void setSzm(char szm){
this.szm = szm;
}
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public void setPhone(long phone){
this.phone = phone;
}
public void setZ_phone(String z_phone){
this.z_phone = z_phone;
}
public void setGender(char gender){
this.gender = gender;
}
public char getSzm(){
return szm;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
public long getPhone(){
return phone;
}
public String getZ_phone(){
return z_phone;
}
public String getZ_phone_area(){
if((z_phone+"").startsWith("0531"))return "济南";
else if((z_phone+"").startsWith("0564"))return "安徽六安";
return "";
}
public char getGender(){
return gender;
}
public boolean equals(Object obj){
Person x = (Person)obj;
if((x.getPhone() + "").equals(this.phone + "") &&
(x.getName()).equals(this.name) &&
(x.getSzm() + "").equals(this.szm + ""))
return true;
else return false;
}
}
这些子类继承父类是因为,他们具有众多相同的属性,方法,我们通过继承可以降低代码的耦合度,是减少工作量的好方法!super()里面把构造方法的参数传到父类,执行父类的构造方法的,当然,我们也需要在子类重载有无座机情况的构造方法。
class Friend extends Person {
public Friend(char szm, String name, int age, char gender, long phone){
super(szm, name, age, gender, phone);
}
public Friend(char szm, String name, int age, char gender, long phone, String z_phone) {
super(szm, name, age, gender, phone, z_phone);
}
}
class Colleague extends Person {
public Colleague(char szm, String name, int age, char gender, long phone) {
super(szm, name, age, gender, phone);}
public Colleague(char szm, String name, int age, char gender, long phone, String z_phone) {
super(szm, name, age, gender, phone, z_phone); }
}
class Relative extends Person {
public Relative(char szm, String name, int age, char gender, long phone) {
super(szm, name, age, gender, phone); }
public Relative(char szm, String name, int age, char gender, long phone, String z_phone) {
super(szm, name, age, gender, phone, z_phone); }
}
class Other extends Person {
public Other(char szm, String name, int age, char gender, long phone) {
super(szm, name, age, gender, phone);}
public Other(char szm, String name, int age, char gender, long phone, String z_phone) {
super(szm, name, age, gender, phone, z_phone);}
}
2、功能模块
A、查看所有联系人
observe观察——OB,显示通讯录的方法,就是这么来的。OB_1_2是分别实现按照不同顺序实现查看的。

public static void OB(){
while(true){
System.out.println("a.按首字母顺序查看\nb.按照组别顺序查看");
String ax = sc.next();
if(ax.equals("a")){OB_1();break;}
else if(ax.equals("b")){OB_2();break;}
else {System.out.println("啊!这样不可以!");}
}
}
OB1,我使用了ANSI码完成了按照首字母进行排序,在循环中用cc计数器控制首字母展示一次。
OB2,我将四个分类存在一个数组中,然后遍历这个数组,随后嵌套一个遍历全部数据的循环,将属于这个类别的人打印出来。
public static void OB_1(){
for(char j = 65; j <= 90 ; j++){
int cc = 0;
for(int i = 0; i < list.size(); i++){
String ax = j + "";
if((list.get(i).getSzm() + "").equals(ax) && cc == 0){
cc++;
System.out.println(ax);
}
if((list.get(i).getSzm() + "").equals(ax)){
System.out.println(list.get(i).getName() + "\t" + list.get(i).getPhone());
}
}
}
}
public static void OB_2(){
String ax[] = {"Friend","Colleague","Relative","Other"};
for(int i = 0; i < 4; i++){
System.out.println(ax[i]);
for(int j = 0; j < list.size(); j++){
if(list.get(j).getClass().getName().equals(ax[i])){
System.out.println(list.get(j).getName() + "\t" + list.get(j).getPhone());
}
}
}
}
B、查找某一位联系人
当时的部分仍然是使用数组存储静态的数据,因此查找是非常简单的部分,因此就不过多讲述了。
public static void find(){
System.out.println("按照名字模糊查找/手机号码进行精确查询");
String ax = sc.next();
for(int i = 0; i < list.size(); i++){
if(list.get(i).getName().equals(ax) || (list.get(i).getPhone()+"").equals(ax)){
System.out.println("姓名:\t\t" + list.get(i).getName());
System.out.println("手机:\t\t" + list.get(i).getPhone());
System.out.println("座机号:\t\t" +
((list.get(i).getZ_phone() == null)? "无座机号码" : list.get(i).getZ_phone()));
System.out.println("座机地区:\t" +
((list.get(i).getZ_phone() == null)? "未知城市" : list.get(i).getZ_phone_area()));
}
}
}
C、添加联系人
(1)校验
这里包含三个方法,一个是可以通用的校验,我们可以输入正则,来制定我们输入的规范,name的输入不适用,是因为我们老师希望我们实现敏感词情况。而座机的检测,我们还需要看是否有"-"是否只有一个"-",开头四个数字是否已经在数据库中,因为我们还没学数据库,因此里面只有两种情况0531和0564。
private static String check(String in,String regex){
while(!in.matches(regex)){
System.out.println("请重新输入:");
in = sc.next();
}
return in;
}
public static boolean check_name(String ax){
if(ax.equals("XJP") || ax.equals("ZEL") || ax.equals("JZM") || ax.equals("MZD") )return false;
return true;
}
public static boolean check_z_phone(String ax){
String bx[] = ax.split("-");
if(bx.length != 2)return false;
if(bx[1].length() != 7)return false;
if((ax.equals("N") || ax.startsWith("0531-") || ax.startsWith("0564-")))return true;
return false;
}
(2)验证码
为了看看我们添加数据的过程中是否是人机,因此输入的内容校验过后,要输入验证码来看看你是不是人机,这一定很合理吧!
public static void Verification(){
String ax = "";
for(int j = 0 ; j < 5 ; j++){
int i = (int)(Math.random()*3);
switch(i){
case 0 : ax = ax + (char)(Math.random() * 26 + 65);break;
case 1 : ax = ax + (char)(Math.random() * 26 + 97);break;
case 2 : ax = ax + (int)(Math.random() * 10);
}
}
System.out.println("请输入一下验证码:" + ax);
while(true){
String bx = sc.next();
if(bx.equalsIgnoreCase(ax))
break;
else{
System.out.println("补药再磨蹭了,快点弄进来叭!");
bx = sc.next();}
}
}
(3)添加
每输入一个值都进行校验,校验成功后下一步,最后进入验证码部分,通过后,根据输入的情况调用适用的构造方法,其实这里用循环嵌套比较简单,只是当时有点小脑,写了一些屎山。不过没有关系!虽然代码复杂了,但是时间复杂度不高.JPG
public static void add(){
String ax;String bx;String cx;String dx;String ex;String fx;String gx;//定义6个局部变量
System.out.println("请选择联系人分类[A:亲人 B:同事 C:朋友 D:其他]");
ax = check(sc.next(),"[ABCD]");
System.out.println("请输入联系人大写首字母:");
bx = check(sc.next(),"[A-Z]");
while(true){
System.out.println("请输入联系人姓名:");
cx = sc.next();
if(check_name(cx))break;}
System.out.println("请输入联系人年龄:");
dx = check(sc.next(),"[0-9]{1,3}");
System.out.println("请选择联系人性别[A:男 B:女]");
ex = check(sc.next(),"[AB]");
System.out.println("请输入联系人手机号码:");
fx = check(sc.next(),"13[0-9]|150|158|159|180|188|187|155[0-9]{8}");
while(true){
System.out.println("请输入联系人座机号码[没有请回复N]");
gx = sc.next();
if(check_z_phone(gx))break;
System.out.println("坏人!每次都说不会干坏事的!");
}
Verification();
char Bx = bx.charAt(0);
int Dx = Integer.parseInt(dx);
char Ex = ex.charAt(0);
Long Fx = Long.parseLong(fx);
if(gx.equals("N")){
if(ax.equals("A")){Relative uu = new Relative(Bx,cx,Dx,Ex,Fx);list.add(uu);}
else if(ax.equals("A")){Colleague uu = new Colleague(Bx,cx,Dx,Ex,Fx);list.add(uu);}
else if(ax.equals("A")){Friend uu = new Friend(Bx,cx,Dx,Ex,Fx);list.add(uu);}
else if(ax.equals("A")){Other uu = new Other(Bx,cx,Dx,Ex,Fx);list.add(uu);}
}
else{
if(ax.equals("A")){Relative uu = new Relative(Bx,cx,Dx,Ex,Fx,gx);list.add(uu);}
else if(ax.equals("A")){Colleague uu = new Colleague(Bx,cx,Dx,Ex,Fx,gx);list.add(uu);}
else if(ax.equals("A")){Friend uu = new Friend(Bx,cx,Dx,Ex,Fx,gx);list.add(uu);}
else if(ax.equals("A")){Other uu = new Other(Bx,cx,Dx,Ex,Fx,gx);list.add(uu);}
}
}
D、删除联系人
这里我们被要求删除前,做一个列表展示我们要删除的内容。然后就是喜闻乐见的校验和删除部分(不是),这部分也是较为简单的。
public static void delete(){
System.out.println("编号\t姓名\t年龄\t手机号");
for(int i = 0; i < list.size(); i ++){
System.out.println(i + "\t" + list.get(i).getName() + "\t" +list.get(i).getAge() + "\t" +
(list.get(i).getPhone()+"").substring(0,3) + "****" + (list.get(i).getPhone()+"").substring(7));
}
System.out.println("输入要删掉的编号吧");
String ax = sc.next();
int cc = 0;
a:while(true){
if(ax.matches("[0-9]{1,4}")){
for(Iterator<Person> car = list.iterator(); car.hasNext(); ){
Person x = car.next();//取出遍历的元素
if(ax.equals(cc + "")){
car.remove();
System.out.println("删好啦!!泰裤辣!!");
break a;
}
cc++;
}
}else{
System.out.println("又在干坏事了!不可以!!出去重输!");
ax = sc.next();
}
}
}
E、修改联系人
(1)判断格式
这个单独出来的判断格式是什么呢?前面不是已经做过了校验格式的方法吗,不可以直接调用吗?不可以!因为老师做了新的要求“请输入要被修改联系人大写首字母-姓名-手机号码[中间用-隔开]”,很合理的要求!!!
public static int modify_PD(){
a:while(true){
System.out.println("请输入要被修改联系人大写首字母-姓名-手机号码[中间用-隔开]");
String ax = sc.next();
String rep = ax.replaceAll("-","");
if((ax.length() - rep.length()) != 3){System.out.println("请输入正确的值哦,亲~");continue a;}
String bx[] = ax.split("-");
if(bx.length != 3){System.out.println("请输入正确的值哦,亲~");continue a;}
for(int i = 0; i < list.size(); i ++){
if(list.get(i).getName().equals(bx[1])&&
(list.get(i).getSzm() + "").equals((bx[0] + ""))&&
(list.get(i).getPhone() + "").equals((bx[2] + ""))){
;return i;}
else{System.out.println("这个没出现过,别想糊弄我!");continue a;}
}
}
}
(2)修改联系人
这里作一下关于校验有“-”的部分的校验的说明吧!我采用的方法是,先删掉字符串中的所有的“-”然后前后长度一减==1,然后用split方法把字符串劈开,再把每个部分分别校验。其他部分也就是有点绕,还是考验基础是否扎实。我超扎实的好吧!当时一下午就敲出来了,而老师给了一整天的时间。
public static void modify(){
int p = modify_PD();
a:while(true){
System.out.println("请输入要被修改联系人大写首字母-姓名-手机号码[中间用-隔开]");
String ax = sc.next();
String rep = ax.replaceAll("-","");
if((ax.length() - rep.length()) != 3){System.out.println("请输入正确的值哦,亲~");continue a;}
String bx[] = ax.split("-");
if(bx.length != 3){System.out.println("请输入正确的值哦,亲~");continue a;}
for(int i = 0; i < list.size(); i ++){
if(list.get(i).getName().equals(bx[1])&&
(list.get(i).getSzm() + "").equals((bx[0] + ""))&&
(list.get(i).getPhone() + "").equals((bx[2] + ""))){
System.out.println("你根本没修改,别想糊弄我!");continue a;}
}
if(bx[0].length() != 1){System.out.println("格式错误!别想糊弄我!");continue a;}
char x = bx[0].charAt(0);
if(check_name(bx[1])){
System.out.println("那是你能冒犯的人吗!别想糊弄我!");continue a;
}
String y = bx[1];
if(!bx[2].matches("138|133|150|158|159|180|188|187|155[0-9]{8}")){
System.out.println("你这手机号保真吗!别想糊弄我!");continue a;
}
Long z = Long.parseLong(bx[2]);
list.get(p).setSzm(x);list.get(p).setName(y);list.get(p).setPhone(z);break;
}
}
三、小结
其实这个应该才算第一个项目,前面发过的那个顶多算练习,还是太简单了,这个就差不多有实训项目的复杂度了,当然是要求比较低的内种,想要分高一些还要搞点更好的东西。
1280

被折叠的 条评论
为什么被折叠?



