Java第六次作业 1502 马 帅

《Java技术》第六次作业

(一)学习总结

2.如下代码:

    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方法的输出结果为:

getMessage 方法的输出结果为:

传播过程:首先通过try{}监视代码块,若在此段代码中出现异常,由catch{}中的代码进行处理。在上述代码中,异常由method3()产生异常,通过method2()和method1()传入try中进行捕获,通过catch进行处理。

3.如下代码:

    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方法是集合自身的方法,内容会被删除,但破坏了集合本身的内容,迭代出现错误,所以才会停止。
若删除的是最后一个元素,可以输出结果但仍有错误,原因同理,在删除之后破坏了集合,使迭代无法继续,所以出现错误。
若要删除集合中的元素,应调用Iterator的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);
        }
    }

4.如下代码:

    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);                
        }
    }

输出结果为:

[Student id=2, name=Rose, Student id=1, name=Jack, Student id=2, name=Rose]

显然,使用HashSet却存入了相同的元素,因为HashSet依靠Object类的hashCode()方法和equals()方法完成重复元素的判断,所以若想去掉重复元素,必须要重写hashCode()方法和equals()方法。
覆写hashCode()方法和equals()方法,代码如下:

    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 int hashCode() {
			final int prime = 31;
			int result = 1;
			result = prime * result + ((id == null) ? 0 : id.hashCode());
			result = prime * result + ((name == null) ? 0 : name.hashCode());
			return result;
		}
		public boolean equals(Object obj) {
			if (this == obj)
				return true;
			if (obj == null)
				return false;
			if (getClass() != obj.getClass())
				return false;
			Student other = (Student) obj;
			if (id == null) {
				if (other.id != null)
					return false;
			} else if (!id.equals(other.id))
				return false;
			if (name == null) {
				if (other.name != null)
					return false;
			} else if (!name.equals(other.name))
				return false;
			return true;
		}
    }
    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);                
        }
    }

5.在hashCode()方法中,eclipse定义了一个系数 final int prime = 31; 为什么这个系数是31呢?为什么就不是32或者21呢?之所以乘以31,其实就是为了尽量保证每个对象的哈希值唯一。在存储的时候可以只通过hashCode方法就可以确定其唯一性,就不用再去麻烦equals方法了。31是个素数(一个大于1的自然数中,除了1和此整数自身外,没法被其他自然数整除的数),这样的数所存在的公倍数就很少。数据存储和查找都是通过hash地址值,所以尽量保证我们得到的哈希值和真实地址值一一对应,从而提高查找效率,而乘以31这个系数可以保证哈希值足够大,而减少重复,也可以保证得出来的哈希值不溢出。

(二)实验总结

1.模拟KTV点歌系统,分别用LinkedList和ArrayList集合,实现一个模拟KTV点歌系统的程序。实现以下功能:
(1)显示歌曲列表
(2)添加歌曲到列表
(3)删除歌曲
(4)将歌曲置顶
(5)将歌曲前移一位
(6)退出
题目扩展:歌曲包括曲名、演唱者。增加排序显示歌曲列表功能。

  • 程序设计思路:
    (1)使用LinkedList集合:
    首先创建LinkedList集合的对象,并向里面初始化一些数据,利用switch..case进行功能的选择;
    添加时,直接添加歌曲名称,其他操作都输入歌曲的序号;
    前移时,使用临时变量进行调换;
    在置顶操作时,使用addFirst()方法置顶,并删除原来的元素。
    (2)使用ArrayList集合:
    首先创建ArrayList集合的对象,并向里面初始化一些数据,利用switch..case进行功能的选择;
    添加时,直接添加歌曲名称,其他操作都输入歌曲的序号;
    前移时,使用临时变量进行调换;
    在置顶操作时,使用add(0,element)方法置顶,并删除原来的元素。
    (3)扩展:
    使用ArrayList集合;
    声明Init类对歌名和歌手构造方法;
    所有操作与上述使用ArrayList集合的方法相同;
    新增一个选项进行排序。
  • 实验问题分析:
    问题:怎样通过拼音对对象数组进行排序?
    解决方案:
    在网上找到了解决方法:Comparator cmp = Collator.getInstance(java.util.Locale.CHINA);
    声明一个String泛型的ArrayList集合,用来保存歌名;
    将歌名从原来的集合中复制到这个集合中,并将它转换为字符数组songname[],调用Arrays.sort(songname,cmp)排序;
    按照排好序的歌名对原集合查找,每找到一个元素就将它复制添加到集合尾部,并将原来的元素删除。
    注意:
    只有当需要排序时才能进行排序,若每执行一次switch..case的其他方法便排序,置顶与前移功能将不能正确输出;
    保存歌名的集合要在排序之后清空。

2.模拟微博用户注册
用HashSet实现一个模拟微博用户注册的程序。用户输入用户名、密码、确认密码、生日(格式yyyy-mm-dd)、手机号码(11位,13、15、17、18开头)、邮箱信息进行微博的注册。要求对用户输入的信息进行验证,输入信息正确后,验证是否重复注册,如果不是则注册成功,否则注册失败。
提示:
(1)设计一个用户类存储用户注册信息
(2)设计一个校验信息类,定义校验方法完成对输入信息的校验。学习使用正则表达式完成对生日、手机号码和邮箱的验证。
(3)设计一个用户注册类模拟注册过程。用HashSet存储用户数据列表,定义一个initData()方法添加初始用户信息。在main方法中完成用户注册功能。

  • 程序设计思路:
    (1)建立一个UsersInformation类用来储存用户的信息;
    (2)建立一个Check类,里面定义若干方法,用正则表达式分别判断用户输入的各个信息是否符合规则;
    (3)在主方法里初始化几个用户信息;
    (4)使用do..while循环进行多次注册,使用switch..case进行判断是注册还是退出;
    (5)在所有信息确认无误后,使用initData方法进行添加完成注册。

  • 实验问题分析:
    问题1:判断输入信息是否重复
    原因:开始时我对每个信息分别进行判断,导致程序出现异常,原因是使用iterator的next()方法时,没有复位,导致hasNext()始终没有其他值。
    解决方案:将信息全部录入后,进行统一的查重。
    问题2:相同的手机或邮箱或用户名而其他两个元素有一个不同,都会被认定为是不同元素
    原因:覆写hashCode()方法中,当用户名、手机、邮箱的值有一个不同,就会返回不同的值,就会被认定为元素不重复。
    解决方案:覆写hashCode()方法,使其返回常数1,使其必须调用覆写的equals()方法,在equals()方法中进行具体的判断。

    注:只要用户名不同则判断为不同的元素,进行输入。

(三)代码托管

  • 码云commit历史截图
posted @ 2017-05-02 11:54  Masart  阅读(210)  评论(0编辑  收藏  举报