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)

参考:

e.printStackTrace()介绍

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()方法进行置顶和前移。

参考

http://blog.csdn.net/top_gun_1/article/details/51065668

故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集,然后在函数中实例化即可。

(三)代码托管

 posted on 2017-05-04 15:22  ben跑的换行符  阅读(411)  评论(1编辑  收藏  举报