参考答案
在企业的项目中,我们通常也会构建一些工具类,用于专门的用途。这些类,大多以XxxUtils作为命名。例如当前案例中要求的RegUtils,主要用于使用正则表达式验证各种信息是否合法。要实现当前案例的需求,需要以下步骤:
首先,构建RegExUtils类,在该类中添加静态常量IDENTITY_CARD、ZIP_CODE以及PHONE_NUMBER分别表示身份证号码、邮政编码以及手机号码的正则表达式。
其次,在RegUtils类中,定义check方法,该方法用于检查字符串str是否和正则表达式regex匹配。
最后,在RegExUtils类中,添加方法identityCard、zipcode以及phoneNumber分别用于实现检测身份证号码、邮政编码以及手机号码是否为合法的。
实现此案例需要按照如下步骤进行。
步骤一:构建工具类RegUtils
在工程JavaSE中,新建类RegExUtils,代码如下所示:
package day02; public class RegExUtils { }
步骤二:定义静态常量表示正则表达式
在RegExUtils类中,添加静态常量IDENTITY_CARD、ZIP_CODE以及PHONE_NUMBER分别表示验证身份证号码、邮政编码以及手机号码的正则表达式,代码如下所示:
package day02; public class RegExUtils { #cold_bold //验证身份证号码的正则表达式 #cold_bold private static final String IDENTITY_CARD = "^\\d{15}|\\d{18}$"; #cold_bold //验证邮政编码的正则表达式 #cold_bold private static final String ZIP_CODE = "^[1-9][0-9]{5}$"; #cold_bold //正则手机号码的正则表达式 #cold_bold private static final String PHONE_NUMBER = "^13[0-9]{9})|(15[89][0-9]{8}$"; }
对于上述正则表达式能看懂即可。
步骤三:构建检查字符串str是否和正则表达式匹配的方法check
在RegExUtils类中,定义check方法,该方法用于检查字符串str是否和正则表达式regex匹配,代码如下所示:
package day02; public class RegExUtils { //验证身份证号码的正则表达式 private static final String IDENTITY_CARD = "^\\d{15}|\\d{18}$"; //验证邮政编码的正则表达式 private static final String ZIP_CODE = "^[1-9][0-9]{5}$"; //正则手机号码的正则表达式 private static final String PHONE_NUMBER = "^13[0-9]{9})|(15[89][0-9]{8}$"; #cold_bold /** #cold_bold * 检查字符串str是否和正则表达式regex匹配 #cold_bold * #cold_bold * @param str #cold_bold * 字符串 #cold_bold * @param regex #cold_bold * 正则表达式 #cold_bold * @return 如果字符串str和正则表达式regex匹配,返回true,否则,返回false #cold_bold */ #cold_bold private static boolean check(String str, String regex) { #cold_bold return str.matches(regex); #cold_bold } }
步骤四:检查
在RegExUtils类中,添加方法identityCard、zipcode以及phoneNumber分别用于实现检测身份证号码、邮政编码以及手机号码是否为合法的,代码如下所示:
package day02; public class RegExUtils { //验证身份证号码的正则表达式 private static final String IDENTITY_CARD = "^\\d{15}|\\d{18}$"; //验证邮政编码的正则表达式 private static final String ZIP_CODE = "^[1-9][0-9]{5}$"; //正则手机号码的正则表达式 private static final String PHONE_NUMBER = "^13[0-9]{9})|(15[89][0-9]{8}$"; /** * 检查字符串str是否和正则表达式regex匹配 * * @param str * 字符串 * @param regex * 正则表达式 * @return 如果字符串str和正则表达式regex匹配,返回true,否则,返回false */ private static boolean check(String str, String regex) { return str.matches(regex); } #cold_bold #cold_bold /** #cold_bold * 检测是否为合法的身份证号码 #cold_bold * #cold_bold * @param str #cold_bold * 身份证号码字符串 #cold_bold * @return 如果身份证号码字符串和正则表达式匹配则返回true,否则返回false #cold_bold */ #cold_bold public static boolean identityCard(String str) { #cold_bold return check(str, IDENTITY_CARD); #cold_bold } #cold_bold #cold_bold /** #cold_bold * 检测是否为合法的邮政编码 #cold_bold * #cold_bold * @param str #cold_bold * 邮政编码字符串 #cold_bold * @return 如果邮政编码字符串和正则表达式匹配则返回true,否则返回false #cold_bold */ #cold_bold public static boolean zipcode(String str) { #cold_bold return check(str, ZIP_CODE); #cold_bold } #cold_bold #cold_bold /** #cold_bold * 检测是否为合法的手机号码 #cold_bold * #cold_bold * @param str #cold_bold * 手机号码字符串 #cold_bold * @return 如果手机号码字符串和正则表达式匹配则返回true,否则返回false #cold_bold */ #cold_bold public static boolean phoneNumber(String str) { #cold_bold return check(str, PHONE_NUMBER); #cold_bold } }
观察上述方法,可以看出,在上述方法中都调用了步骤二定义check方法,check方法的重用率很高,这也是单独定义check方法的原因。
本案例中,RegExUtils的完整代码如下所示:
package day02; public class RegExUtils { //验证身份证号码的正则表达式 private static final String IDENTITY_CARD = "^\\d{15}|\\d{18}$"; //验证邮政编码的正则表达式 private static final String ZIP_CODE = "^[1-9][0-9]{5}$"; //正则手机号码的正则表达式 private static final String PHONE_NUMBER = "^13[0-9]{9})|(15[89][0-9]{8}$"; /** * 检查字符串str是否和正则表达式regex匹配 * * @param str * 字符串 * @param regex * 正则表达式 * @return 如果字符串str和正则表达式regex匹配,返回true,否则,返回false */ private static boolean check(String str, String regex) { return str.matches(regex); } /** * 检测是否为合法的身份证号码 * * @param str * 身份证号码字符串 * @return 如果身份证号码字符串和正则表达式匹配则返回true,否则返回false */ public static boolean identityCard(String str) { return check(str, IDENTITY_CARD); } /** * 检测是否为合法的邮政编码 * * @param str * 邮政编码字符串 * @return 如果邮政编码字符串和正则表达式匹配则返回true,否则返回false */ public static boolean zipcode(String str) { return check(str, ZIP_CODE); } /** * 检测是否为合法的手机号码 * * @param str * 手机号码字符串 * @return 如果手机号码字符串和正则表达式匹配则返回true,否则返回false */ public static boolean phoneNumber(String str) { return check(str, PHONE_NUMBER); } }
在面向对象的课程中,我们曾使用过Emp类,本案例要求重写Emp类的toString方法和equals方法,详细要求如下:
1),重写Emp类的toString方法,返回Emp对象的名字、年龄、性别和工资信息,例如:张三,23,男,5000。
2),重写Emp类的equals方法,两个Emp引用变量相等的条件是名字相等。
参考答案
实现此案例需要按照如下步骤进行。
步骤一:创建 Emp类
创建 Emp类,并在其中覆盖toString方法,返回Emp对象的名字,年龄,性别和工资信息,代码如下所示:
package day02; public class Emp { String name; int age; char gender; double salary; public void printInfo() { System.out.println("--------------------"); System.out.println("姓名: " + name); System.out.println("年龄:" + age); System.out.println("性别:" + gender); System.out.println("薪水:" + salary); } @Override public String toString() { return name + "," + age + "," + gender + "," + salary; } }
步骤二:写测试方法
测试toString方法是否覆盖生效。首先,在JavaSE工程下的day02包下新建TestEmp,然后,在该类中添加测试方法testToString,最后,实例化一个Emp类的对象,其name、age、gender、salary为张三、23、男、5000,并输出该对象,代码如下所示:
package day02; import org.junit.Test; public class TestEmp { /** * 测试toString方法 */ @Test public void testToString() { Emp emp = new Emp(); emp.name="张三"; emp.age=23; emp.gender='男'; emp.salary=5000; System.out.println(emp); // 张三,23,男,5000 } }
步骤三:运行
运行testToString方法,控制台输出结果如下所示:
张三,23,男,5000
从运行结果可以看出,已经成功覆盖了toString方法,返回name、age、gender、salary的值为张三,23,男,5000。
步骤四:在Emp类中覆盖equals方法
在Emp类中覆盖equals方法,两个Emp引用变量相等的条件是名字相等,代码如下所示:
package day02; public class Emp { String name; int age; char gender; double salary; public void printInfo() { System.out.println("--------------------"); System.out.println("姓名: " + name); System.out.println("年龄:" + age); System.out.println("性别:" + gender); System.out.println("薪水:" + salary); } @Override public String toString() { return name + "," + age + "," + gender + "," + salary; } #cold_bold @Override #cold_bold public boolean equals(Object obj) { #cold_bold if (obj == null) { #cold_bold return false; #cold_bold } #cold_bold if (this == obj) { #cold_bold return true; #cold_bold } #cold_bold if (obj instanceof Emp) { #cold_bold Emp emp = (Emp) obj; #cold_bold return this.name.equals(emp.name); #cold_bold } else { #cold_bold return false; #cold_bold } #cold_bold } }
此处需要注意,属性name的类型为String类型,比较两个字符序列是否相等使用equals方法。
步骤五:测试equals方法是否生效
测试equals方法是否覆盖生效。首先,在类TestEmp中添加测试方法testEquals,然后,创建emp1对象和emp2对象; 最后,分别使用==和equals比较emp1对象和emp2对象是否相等,代码如下所示:
package day02; import org.junit.Test; public class TestEmp { /** * 测试toString方法 */ @Test public void testToString() { Emp emp = new Emp(); emp.name="张三"; emp.age=23; emp.gender='男'; emp.salary=5000; System.out.println(emp); // 张三,23,男,5000 } #cold_bold /** #cold_bold * 测试equals方法 #cold_bold */ #cold_bold @Test #cold_bold public void testEquals() { #cold_bold Emp emp1 = new Emp(); #cold_bold emp1.name="张三"; #cold_bold emp1.age=24; #cold_bold emp1.gender='女'; #cold_bold emp1.salary=6000; #cold_bold Emp emp2 = new Emp(); #cold_bold emp2.name="张三"; #cold_bold emp2.age=23; #cold_bold emp2.gender='男'; #cold_bold emp2.salary=5000; #cold_bold System.out.println(emp1 == emp2); // false #cold_bold System.out.println(emp1.equals(emp2)); // true #cold_bold } }
步骤六:运行
运行testEquals方法,控制台输出结果如下所示:
false true
从运行结果可以看出,使用==比较的结果为false、使用equals比较的结果为true,说明Emp类成功覆盖了equals方法,实现了名字(name)相等两个Emp的引用变量则相等。
本案例中,Emp类的完整代码如下所示:
package day02; public class Emp { String name; int age; char gender; double salary; public void printInfo() { System.out.println("--------------------"); System.out.println("姓名: " + name); System.out.println("年龄:" + age); System.out.println("性别:" + gender); System.out.println("薪水:" + salary); } @Override public String toString() { return name + "," + age + "," + gender + "," + salary; } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (this == obj) { return true; } if (obj instanceof Emp) { Emp emp = (Emp) obj; return this.name.equals(emp.name); } else { return false; } } }
TestEmp类的完整代码如下:
package day02; import org.junit.Test; public class TestEmp { /** * 测试toString方法 */ @Test public void testToString() { Emp emp = new Emp(); emp.name="张三"; emp.age=23; emp.gender='男'; emp.salary=5000; System.out.println(emp); // 张三,23,男,5000 } /** * 测试equals方法 */ @Test public void testEquals() { Emp emp1 = new Emp(); emp1.name="张三"; emp1.age=24; emp1.gender='女'; emp1.salary=6000; Emp emp2 = new Emp(); emp2.name="张三"; emp2.age=23; emp2.gender='男'; emp2.salary=5000; System.out.println(emp1 == emp2); // false System.out.println(emp1.equals(emp2)); // true } }
用户从控制台接收一个字符串,通过程序判断该字符串是整数,还是小数。如果既不是整数也不是小数,程序输出“数字格式不正确”。程序交互过程如下所示:
用户输入整数字符串的情况,如图-1所示:
图- 1
用户输入为小数的情况,如图-2所示:
图- 2
用户输入的既不是整数也不是小数的情况,如图-3所示:
图- 3
参考答案
实现此案例需要按照如下步骤进行。
步骤一:新建TestChange类,添加testStringToIntOrDouble方法
首先,在工程JavaSE的day02包下新建类TestChange;然后,在该类中添加方法testStringToIntOrDouble,代码如下所示:
package day02; import java.util.Scanner; import org.junit.Test; public class TestChange { @Test public void testStringToIntOrDouble() { } }
步骤二:定义正则表达式
定义匹配整数和匹配小数的正则表达式,代码如下所示:
package day02; import org.junit.Test; public class TestChange { @Test public void testStringToIntOrDouble() { #cold_bold String integerRegex = "^[0-9]+$"; #cold_bold String decimalRegex = "^[0-9]+\\.[0-9]+$"; } }
步骤三:对用户输入的字符串进行判断
首先,接收用户输入的字符串;然后,使用字符串的matches方法判断该字符串是整数还是小数或是其它情况,代码如下所示:
package day02; import java.util.Scanner; import org.junit.Test; public class TestChange { @Test public void testStringToIntOrDouble() { String integerRegex = "^[0-9]+$"; String decimalRegex = "^[0-9]+\\.[0-9]+$"; #cold_bold Scanner scanner = new Scanner(System.in); #cold_bold System.out.println("请输入一个数字:"); #cold_bold String numberStr = scanner.nextLine(); #cold_bold if(numberStr.matches(integerRegex)){ #cold_bold System.out.println("这是一个整数:"+Integer.parseInt(numberStr)); #cold_bold }else if(numberStr.matches(decimalRegex)){ #cold_bold System.out.println("这是一个小数:"+Double.parseDouble(numberStr)); #cold_bold }else{ #cold_bold System.out.println("数字格式不正确!"); #cold_bold } } }
上述代码中,使用Integer的parseInt方法将字符串转换为整数、使用Double的parseDouble方法将字符串转换为浮点数。
本案例的完整代码如下所示:
package day02; import java.util.Scanner; import org.junit.Test; public class TestChange { @Test public void testStringToIntOrDouble() { String integerRegex = "^[0-9]+$"; String decimalRegex = "^[0-9]+\\.[0-9]+$"; Scanner scanner = new Scanner(System.in); System.out.println("请输入一个数字:"); String numberStr = scanner.nextLine(); if(numberStr.matches(integerRegex)){ System.out.println("这是一个整数:"+Integer.parseInt(numberStr)); }else if(numberStr.matches(decimalRegex)){ System.out.println("这是一个小数:"+Double.parseDouble(numberStr)); }else{ System.out.println("数字格式不正确!"); } } }
参考答案
装箱和拆箱是 “编译器”认可的,而不是虚拟机。编译器在生成类的字节码时,插入必要的方法调用,例如:
将自动装箱处理为:
Integer a = 100 => Integer a = Integer.valueOf(100) Integer b = 200 => Integer b = Integer.valueOf(200) Integer c = a +b => Integer c = Integer.valueOf (a.intValue( ) + b.intValue( ))
可以看出,自动装箱时,调用了Integer的valueOf方法将int类型的值100转换成了Integer类型。
自动拆箱处理为:
int d = c => int d = c . intValue( )
可以看出,自动拆箱时,调用了Integer的intValue方法,将Integer类型的变量转成了int类型。