Java第六次作业--异常处理和Java类集
(一)学习总结
1.用思维导图对本周的学习内容进行总结。
2.当程序中出现异常时,JVM会依据方法调用顺序依次查找有关的错误处理程序。可使用printStackTrace 和getMessage方法了解异常发生的情况。阅读下面的程序,说明printStackTrace方法和getMessage 方法的输出结果分别是什么?并分析异常的传播过程。
public class PrintExceptionStack {
public static void main( String args[] )
{
try {
method1();
} catch ( Exception e ) {
System.err.println( e.getMessage() + "\n" );
e.printStackTrace();
}
}
public static void method1() throws Exception
{
method2();
}
public static void method2() throws Exception
{
method3();
}
public static void method3() throws Exception
{
throw new Exception( "Exception thrown in method3" );
}
}
printStackTrace
方法是在命令行打印异常信息在程序中出错的位置及原因。输出为:
java.lang.Exception: Exception thrown in method3
at PrintExceptionStack.method3(PrintExceptionStack.java:23)
at PrintExceptionStack.method2(PrintExceptionStack.java:19)
at PrintExceptionStack.method1(PrintExceptionStack.java:15)
at PrintExceptionStack.main(PrintExceptionStack.java:5)
参考:
getMessage
方法的输出结果是:Exception thrown in method3
异常的传播过程:
try{}语句中包括可能产生异常的语句,catch{}进行对出现的异常进行捕获。采用了throws的捕获异常,所有在调用method1()
方法时需要处理异常,但是在method1()
中进行throws,所有在调用该方法的时候需要处理,一直到method3()
的时候处理了该异常。catch语句中输出了getMessage
,信息,为Exception e.get方法。即输出: java.lang.Exception: Exception thrown in method3
`e.printStackTrace();`
则输出:
at PrintExceptionStack.method3(PrintExceptionStack.java:23)
at PrintExceptionStack.method2(PrintExceptionStack.java:19)
at PrintExceptionStack.method1(PrintExceptionStack.java:15)
at PrintExceptionStack.main(PrintExceptionStack.java:5)
3.阅读下面程序,分析程序的运行结果,解释产生错误的原因,如果删除的是books集合的最后一个对象,运行的结果又是什么?你能对此作出解释吗?如果在遍历时非要删除集合中的元素,应如何实现?
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Collection<String> books = new ArrayList<String>();
books.add("One book");
books.add("Two book");
books.add("Three book");
System.out.println("原始元素之后:"+books);
Iterator<String> it = books.iterator();
while(it.hasNext())
{
String book = (String)it.next();
System.out.println(book);
if (book.equals("One book"))
{
books.remove(book);
}
}
System.out.println("移除元素之后:"+books);
}
}
产生错误的原因:在迭代时,如果调用集合对象的remove()方法删除对象,会出现运行错误。
可以修改为:
import java.util.*;
public class Test {
public static void main(String[] args) {
Collection<String> books = new ArrayList<String>();
books.add("One book");
books.add("Two book");
books.add("Three book");
System.out.println("原始元素之后:" + books);
Iterator<String> it = books.iterator();
while (it.hasNext()) {
String book = (String) it.next();
System.out.println(book);
if (book.equals("One book")) {
it.remove();
}
}
System.out.println("移除元素之后:" + books);
}
}
使用Iterator自身的remove方法即可
输出的结果为:
删除最后一个对象:只需要将
if (book.equals("One book")) {
it.remove();
}
中的equals方法中的字符串更改为你想要删除的对象字符串即可,就可以在遍历的过程中删除对象。
4.HashSet存储的元素是不可重复的。运行下面的程序,分析为什么存入了相同的学生信息?如果要去掉重复元素,应该如何修改程序。
import java.util.*;
class Student {
String id;
String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "Student id=" + id + ", name=" + name ;
}
}
public class Test
{
public static void main(String[] args)
{
HashSet<Student> set = new HashSet<Student>();
set.add(new Student("1","Jack"));
set.add(new Student("2","Rose"));
set.add(new Student("2","Rose"));
System.out.println(set);
}
}
在set.add方法中使用匿名对象,虽然内容相同,但是由于是匿名对象,内容虽然相同但引用的地址不相同,故在HashSet接口中仍能实现。
修改后的程序为:
import java.util.*;
class Student {
String id;
String name;
public Student(String id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return "Student id=" + id + ", name=" + name ;
}
public boolean equals(Object obj){
if(this==obj){
return true;
}
if(!(obj instanceof Student)){
return false;
}
Student s=(Student) obj;
if(this.name.equals(s.name)&&this.id.equals(s.id)){
return true;
}else{
return false;
}
}
public int hashCode(){
return (this.id.hashCode()+this.name.hashCode());
}
}
public class Test
{
public static void main(String[] args)
{
HashSet<Student> set = new HashSet<Student>();
Student s1=new Student("1","Jack");
Student s2=new Student("2","Rose");
Student s3=new Student("2","Rose");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set);
}
}
总结
产生异常的时候java中有专门的异常类进行实例化,然后进行捕获。Exception
这个类是最大的类,在进行catch捕获的时候如果用到该类,需要在最后进行实例化。
关于内存中的引用,
Student s1=new Student("1","Jack");
Student s2=new Student("2","Rose");
Student s3=new Student("2","Rose");
set.add(s1);
set.add(s2);
set.add(s3);
其中匿名对象进行实例化和使用类实例化的对象其产生的效果一样,即同一个对象,采用类实例化和采用匿名对象实例化引用地址都是相同。
对于s2和s3来说,引用地址不同,故采用HashSet仍能输出。
(二)实验总结
实验内容:
1.模拟KTV点歌系统
分别用LinkedList和ArrayList集合,实现一个模拟KTV点歌系统的程序。实现以下功能:
(1)显示歌曲列表
(2)添加歌曲到列表
(3)删除歌曲
(4)将歌曲置顶
(5)将歌曲前移一位
(6)退出
题目扩展:歌曲包括曲名、演唱者。增加排序显示歌曲列表功能。
设计思路:
LinkedList基本和ArrayList程序一样,添加歌曲到List集中,然后进行遍历,添加等操作。
问题1:置顶歌曲
解决:先定义一个String类型的变量来接受要置顶的歌曲信息,然后删除要置顶的歌曲信息,然后在添加到第一个位置,由于是从0开始计数,故在方法最开始就是变量-1;
public static void toFirst(List<String> l, int z) {
z = z - 1;
String temp = l.get(z);
l.remove(z);
l.add(0, temp);
}
由于位置有限,故只截取部分截图
题目扩展:歌曲包括曲名、演唱者。增加排序显示歌曲列表功能。
设计思路:
先定义一个Song
类来存储信息,考虑到排序问题,故采用TreeMap定义,定义Map为static静态,然后在初始化歌曲列表的时候实例化该对象,开辟内存来进行存储信息,使用Itreator迭代器进行遍历。然后使用java8方法中的map.replace()方法进行置顶和前移。
参考
故java版本小于1.8的会出现报错信息。可以重新构建jre系统库,官网下载最新版本的java然后将jre添加到备用即可。实验室内装的java版本为1.8。
由于采用的是TreeMap集的存储,故开始存数据的时候就进行了排序。
问题:Map中的元素一直为空
解决:使用全局变量对Map进行修饰即可,在函数中使用则实例化,但是只能实例化一次,如果在另一个函数中接着实例化,则相当于使用Map.clear(),重新分配了空间。
private static Map<String, Song> map = null;
2.模拟微博用户注册
用HashSet实现一个模拟微博用户注册的程序。用户输入用户名、密码、确认密码、生日(格式yyyy-mm-dd)、手机号码(11位,13、15、17、18开头)、邮箱信息进行微博的注###册。要求对用户输入的信息进行验证,输入信息正确后,验证是否重复注册,如果不是则注册成功,否则注册失败。
提示:
(1)设计一个用户类存储用户注册信息
(2)设计一个校验信息类,定义校验方法完成对输入信息的校验。学习使用正则表达式完成对生日、手机号码和邮箱的验证。
(3)设计一个用户注册类模拟注册过程。用HashSet存储用户数据列表,定义一个initData()方法添加初始用户信息。在main方法中完成用户注册功能。
设计思路:
定义User
类进行存储信息,重写hashCode方法,和equals方法。
定义一个check
类进行来写验证方法。
定义一个Test
类进行验证。在Test
类中实例化check
类的对象,然后调用里面的各种方法进行验证即可。
问题:同Map一样无法存进去数据
解决:使用全局变量来定义Set集,然后在函数中实例化即可。