【实现思路】
1、为了便于存储用户的信息,需要创建一个用户类,在类中重写其中的 HashCode()方法,令其返回用户名的哈希值,再重写 equals()方法,来比较对象的用户名属性是否相等。
2、有了用户类后,还需要创建一个用户注册类来模拟注册信息,该类中可以用 HashSet 集合来创建一个数据列表,然后向列表中添加两条初始用户信息。
3、从控制台获取用户填写信息,可以通过 Scanner 类的 nextLine()方法来实现,获取后,需要将获取的信息进行检验。
4、检验信息可以单独创建一个校验信息类,在类中实现校验用户输入信息的方法。校验结束后,如果校验结果错误就直接返回错误信息,这里可以分别声明一个校验结果变量和一个校验状态变量。校验结果变量用于存储提示信息,校验状态可用于存储结果的判断标识。
5、当用户输入的信息不满足规定格式时,需要修改变量并存储错误信息。
6、判断校验状态,如果所有信息都通过校验,则将用户信息创建成为用户对象,通过将对象添加到用户列表返回结果来判断用户名是否重复,并记录下返回结果信息。
【实现代码】
1、创建用户类,并重写 HashCode()方法和 equals()方法,代码如下所示。
import java.util.Date;
public class User {
private String userName;
private String password;
private Date brithday;
private String telNumber;
private String email;
//构造空参方法
public User() {
}
//构造方法
public User(String userName, String password, Date brithday, String telNumber, String email) {
super();
this.userName = userName;
this.password = password;
this.brithday = brithday;
this.telNumber = telNumber;
this.email = email;
}
//重写 hashCode 和 equals 方法
@Override
public int hashCode() {
return userName.hashCode(); //重写 hashCode()方法,以用户名作为是重复的判断依据
}
@Override
public boolean equals(Object obj) {
if (this == obj) //判断是否为同一个对象
return true; //如果是同一个对象,直接返回 true
if (obj == null) //判断这个对象是否为空
return false; //如果对象是空的,直接返回 false
if (getClass() != obj.getClass()) //判断这个对象是否是 User 类型
return false; //如果不是,直接返回 false
User other = (User) obj; //传入的 object 原是 User 对象,传入时自动向上转型为 Object 类,equals 方法中需要比较 User 中的属性内容,即 User 的对象里的内容,所以要再强转回来
if (userName == null) { //判断集合中已有的用户名是否为空(是否已有数据存入)
if (other.userName != null) //判断 obj 对象中的用户名是否为空
return false; //集合中用户名为空且对象中用户名不为空,则返回 false
} else if (!userName.equals(other.userName)) //判断用户名是否相同
return false; //如果不同,则返回 false
return true; //说明用户名相同,返回 true
}
}
在重写 equals()方法时,遇到很大的困难,翻了书看了教学视频都没有详细的解释为何在重写方法时要强制转型,后利用搜索引擎,找到了几篇大概像个合理的解释的解释。
在 Java 的继承中,子类可以转换成父类,在此过程中会丢失一些属性,不需要进行强制类型的转换。但父类转成子类就不行了,必须进行类型的强转。重写 equals()方法需要传入 object 对象,obj 对象是子类对象自动向上转型而来,在第三次if判断后,进行第四次 if 判断时,需要比较子类对象的属性,所以需要进行类型的强转。
当使用类型构造器构造处一个对象的容器时,这个对象的类型是确定的,本质上是不会发生变化的。所以,在继承中,子类可以自动转型成父类,但父类强制转换为子类时只有当引用类型真正为子类时才会强制转换成功,否则失败。
2、创建用户信息类,模拟注册信息,代码如下所示。
import java.util.Date;
import java.util.HashSet;
import java.util.Scanner;
public class UserRegister {
public static HashSet<User> USER_DATA = new HashSet<User>(); //存储用户数据
public static void main(String[] args) {
//初始化人员信息
initData();
//注册新用户,填写注册信息
Scanner scanner = new Scanner(System.in);
System.out.print("请输入用户名:");
String username = scanner.nextLine(); //获取用户名
System.out.print("请输入密码:");
String password = scanner.nextLine(); //获取密码
System.out.print("请再次输入密码:");
String repassword = scanner.nextLine(); //获取重复密码
System.out.print("出生日期:");
String birthday = scanner.nextLine(); //获取出生日期
System.out.print("手机号码:");
String telNumber = scanner.nextLine(); //获取手机号码
System.out.print("电子邮箱:");
String email = scanner.nextLine(); //获取电子邮箱
//校验用户信息,返回注册状态信息
CheckInfo checkInfo = new CheckInfo(USER_DATA);
String result = checkInfo.checkAction(username,password,repassword,birthday,telNumber,email);
System.out.println("注册结果:" + result);
System.out.println(USER_DATA.toString());
}
//初始化数据,创建两个已存在的用户信息并添加至集合
private static void initData() {
//创建两个 User 对象,添加到集合中
User user = new User("张正","zz,123",new Date(),"18872378493","zhangzheng@itcast.cn");
User user2 =new User("周琦","zq,123",new Date(),"19151444656","zhouqi@itcast,cn");
USER_DATA.add(user);
USER_DATA.add(user2);
}
}
当程序运行 main()方法后,首先会执行第 31-37 行代码,初始化人员信息,创建“张正”、“周琦”两位用户,并放入用户数据列表中,然后执行第 11-29 行代码,获取输入的信息并将其传入 CheckInfo 类的 checkAction()方法对输入信息进行校验,最后将结果输出。
3、创建校验信息类,代码如下所示。
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashSet;
public class CheckInfo {
public static HashSet<User> USER_DATA = new HashSet<User>(); //用户数据
//构造方法
public CheckInfo (HashSet<User> USER_DATA) {
this.USER_DATA = USER_DATA;
}
//校验用户信息,返回注册状态信息
public String checkAction(String userName , String password , String repassword , String birthday , String phone , String email) {
//状态 1、代表成功 2、代表失败
int state = 1;
//创建字符串缓冲区,记录返回的注册结果内容的字符串
StringBuilder result = new StringBuilder();
//第一步,验证用户输入的注册信息
//密码判断
if (!password.equals(repassword)) { //判断密码和重复密码是否相同
result.append("两次输入的密码不一致! \r\n");
state = 2; //修改状态为注册失败
}
//生日判断
if (birthday.length() != 10) { //字符串长度不为 10,则认定格式错误
result.append("生日格式不正确! \r\n");
state = 2; //修改状态为注册失败
}else {
for (int i = 0; i < birthday.length(); i++) {
//char thisChar = birthday.charAt(i);
Character thisChar = birthday.charAt(i); //Character包装类 -- char类型
if (i == 4 || i ==7) {
if(!(thisChar == '-')) { //验证第四位和第七位是否是符号“-”
result.append("生日格式不正确! \r\n");
state = 2; //修改状态为注册失败
}
}else { //验证除了第四位和第七位的字符是否是 0~9 的数字
if(!(Character.isDigit(thisChar))) { //调用 isDigit()方法必须使用包装类,所以不使用 char 类型
result.append("生日格式不正确! \r\n");
state = 2; //修改状态为注册失败
}
}
}
}
//手机号码判断
if (phone.length() != 11) { //判断手机号长度不等于 11 位则认为此手机号无效
result.append("手机号码不正确!\r\n");
state = 2; //修改状态为注册失败
//默认有效手机号为 13、15、17 和 18 开头的手机号,如果不是,则认为此手机号无效
}else if (!(phone.startsWith("13") || phone.startsWith("15") || phone.startsWith("17") || phone.startsWith("18"))) {
result.append("手机号码不正确! \r\n");
state = 2; //修改状态为注册失败
}
//邮箱判断
if (!email.contains("@")) { //判断邮箱地址,默认不带@符号的邮箱认为无效邮箱
result.append("邮箱不正确! \r\n");
state = 2; //修改状态为注册失败
}
//如果以上信息校验无误,则将新用户加入到集合
//第二步,验证新用户在已有用户中是否存在
if (state == 1) {
//把日期字符串解析成日期对象。//格式化日期返回 Date 对象
DateFormat format = new SimpleDateFormat("yyyy-MM-dd"); //定义日期
Date dateBirthday = null;
try {
dateBirthday = format.parse(birthday); //调用 parse()方法解析日期存入 dateBirthday
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//将新用户添加到列表中,同时可根据 HashSet 判断出用户名有没有重复
User newUser = new User(userName,password,dateBirthday,phone,email);
if (USER_DATA.add(newUser)) {
result.append("注册成功!");
}else {
result.append("用户重复!"); //在 HashSet 集合中,无法添加重复元素
state = 2; //修改状态为注册失败
}
}
return result.toString();
}
}
校验信息类看上去有些繁琐,仔细研究下倒也不是太难。主要步骤分两步,第一步检验用户输入的信息是否符合格式,所有校验通过后,将信息创建为 User 对象,第二步则利用 equals()方法返回的结果,验证是否与本地已存在用户重复。
创建 User 对象时需要注意一下,生日是 date 类型,不是 string 类型,需要进行类型转换,格式化日期返回 date 对象。但是在存入对象时提示报错,可能存在类型转化问题,于是需要使用 cry catch 抛出异常。