码迷,mamicode.com
首页 > 编程语言 > 详细

Java 异常处理机制和集合框架

时间:2015-11-01 10:10:49      阅读:257      评论:0      收藏:0      [点我收藏+]

标签:

课程  Java面向对象程序设计   实验名称  异常处理机制、集合框架 

班级    13计三          学号  10503                姓名                  

一、实验目的

掌握面向对象程序设计技术

二、实验环境

1微型计算机一台 

2WINDOWS操作系统,Java SDK,Eclipse开发环境

三、实验内容 

1、Java异常处理机制涉及5个关键字:try、catch、finally、throw、throws,请理解每个关键字的作用,并在编写程序,使用运用这5个关键字,观察效果。

2、设计学生类(是一个javaBean),包含年龄和姓名(均私有)。

3、Java常用的集合类有:HashSet、TreeSet(红黑树)、ArrayList、Stack、HashMap(用学生类的年龄作为键值)、Properties,请编写程序,分别使用运用这些集合类,来存储学生类对象。

4、请问java中有没有优先队列实现类,如果有,请编写程序,演示该类的使用。

四、实验步骤和结果

1、Java异常处理机制涉及5个关键字:try、catch、finally、throw、throws,请理解每个关键字的作用,并在编写程序,使用运用这5个关键字,观察效果。

(1)try和catch

try的意思是测试它所包含的代码是否会发生异常,而catch 的意思就是在异常发生时就抓住它,并进行相应的处理,使程序不受该异常的影响从而继续执行下去。

它们通常使用的格式如下:

Try{

  //代码段(可能会发生异常的代码)

} catch (异常类型 ex) {

  //对异常进行处理的代码段

}

//代码段

测试代码(MoreCatchDemo.java)如下所示:(注意:当有多个catch,在安排catch语句的顺序时,首先应该捕获子类异常,然后再捕获父类异常)

import java.util.InputMismatchException;

import java.util.Scanner;

public class MoreCatchDemo {

/*** @param args */

public static void main(String[] args) {

Scanner in=new Scanner(System.in);

try {

   System.out.println("请输入第一个学期的总学时:");

  int totalTime=in.nextInt();//总学时

  System.out.println("请输入第一个学期的总课程:");

  int totalCourse=in.nextInt();//课程总数

  System.out.println("第一学期各个课程的平均学时为:"+totalTime/totalCourse);

} catch (InputMismatchException e1) {

  // TODO: handle exception

  System.out.println("输入不为数字!");

}catch (ArithmeticException e2) {

  // TODO: handle exception

  System.out.println("课程数目不能为0!");

}catch (Exception e) {

  // TODO: handle exception

  System.out.println("发生错误:"+e.getMessage());

}

  System.out.println("我是catch后面的代码。");

}

}

(2) finally

   在某些特定的情况下,不管是否有异常发生,总是要求某些特定的代码必须被执行,这就需要用到finally 关键字。

测试代码(FinallyDemo.java)如下所示:

public class FinallyDemo {

/**  * @param args */

  public static void main(String[] args) {

  System.out.println("请打开数据连接……");

  try {

    System.out.println("执行查询操作");

    System.out.println("执行修改操作");

    int i=12/0;

    System.out.println("执行添加操作");

    System.out.println("执行删除操作");

} catch (Exception e) {

    // TODO: handle exception

     System.out.println("除零出错!");

    e.printStackTrace();

}  finally{

  System.out.println("请关闭数据连接……");

}

}

}

(3)throw

      throw 语句用来明确地抛出一个“异常”。需要注意的是,用户必须得到一个Throwable类或者其他子类产生的实例句柄,通过参数传到catch字句,或者用 new语句来创建一个实例。throw 总是出现在函数体中,用来抛出一个异常。程序会在throw语句后立即终止,它后面的语句执行不到,throw后必须抛出一个Throwable类的实例。

测试代码(ThrowDemo.java)如下所示:

public class ThrowDemo {

   /**  * @param args  */

  public static void main(String[] args) {

  // TODO Auto-generated method stub

  int number=0;

  try {

  number=Integer.parseInt(args[0]);

   } catch (Exception e) {

    // TODO: handle exception

    throw new ArrayIndexOutOfBoundsException("数组越界!");

    //System.out.println("非法的数字");

}

    System.out.println("你输入的数字为:"+number);

}

}

(4)throws

  Throws 用来声明一个方法可能会抛出的所有异常,它跟在方法签名的后面。

若这个方法可以引发异常,而它本身并不对该异常进行处理,那么该方法必须将这个异常抛给调用者以使程序能够继续执行下去。如果有多个异常,则使用逗号将其分开。

测试代码(ThrowsDemo.java)如下所示:

public class ThrowsDemo {

/**  * @param args*/  

public static void main(String[] args) {

testThrows(args);

}

private static void testThrows(String[] tmp) {

try {

createThrow(tmp);

} catch (Exception e) {

System.out.println("来自createThrow方法的异常");

}

}

//抛出可能的异常

private static void createThrow(String[] tmp) throws Exception {

int number=3;

System.out.println("你输入的数字为:"+number+‘\n‘);

number=Integer.parseInt(tmp[0]);

System.out.println("你输入的数字为:"+number);

}

}

(5)throw和throws语句的组合使用

    一般都需要throw和throws语句的组合使用,就是在捕获异常后,抛出一个明确的异常给调用者。

测试代码(ThrowAndThrowsDemo.java)如下所示:

public class ThrowAndThrowsDemo {

/*** @param args*/

public static void main(String[] args) {

// TODO Auto-generated method stub

testThrow(args);

}

     //调用有异常的方法

private static void testThrow(String[] tmp) {

// TODO Auto-generated method stub

try {

createThrow(tmp);

} catch (Exception e) {

System.out.println("捕捉来自createThrow方法的异常");

}

}

    //抛出一个具体的异常

private static void createThrow(String[] tmp) throws Exception {

// TODO Auto-generated method stub

int number=0;

try {

number=Integer.parseInt(tmp[0]);

} catch (Exception e) {

// TODO: handle exception

throw new ArrayIndexOutOfBoundsException("数组越界");

}

System.out.println("你输入的数字为:"+number);

}

}

2、设计学生类(是一个javaBean),包含年龄和姓名(均私有)。

测试代码(StudentJavaBean.java)如下所示:

//StudentJavaBean:

//1.有一个无参的公共的构造方法

//2.有属性,属性最好定义为私有的。

//3.有与属性对应的get、set存取方法

//public class StudentJavaBean implements Comparable {  //在实现TreeSetTest中,这里接口是必须的

public class StudentJavaBean  { 

      private int age;

      private String name;

      private Integer score;

 public StudentJavaBean() {  } //无参构造方法

      public StudentJavaBean(int age, String name,int score) {

super();

this.age = age;

this.name = name;

this.score=score;

}

//与属性对应的get、set存取方法

  public String getName() {

return name;

  }

  public void setName(String name) {

this.name = name;

}

 public Integer getAge() {

return age;

}

 public void setAge(Integer age) {

this.age = age;

}

 public Integer getScore() {

return score;

}

public void setScore(Integer score) {

this.score = score;

}

 //要显示Student的信息,必须重写toString()方法

 public String toString() {

return "StudentJavaBean [age=" + age + ", name=" + name +",score="+ score+ "]";

}

3、Java常用的集合类有:HashSet、TreeSet(红黑树)、ArrayList、Stack、HashMap(用学生类的姓名作为键值)、Properties,请编写程序,分别使用运用这些集合类,来存储学生类对象。

(1)HashSet

测试代码(HashSetTest.java)如下所示:

import java.util.HashMap;

import java.util.HashSet;

import java.util.Iterator;

public class HashSetTest {

/** @param args */

public static void main(String[] args) {

// TODO Auto-generated method stub

HashSet hs=new HashSet();

hs.add(new StudentJavaBean(19,"张三",80));

hs.add(new StudentJavaBean(18,"李四",90));

hs.add(new StudentJavaBean(20,"黄七",85));

hs.add(new StudentJavaBean(17,"王五",95));

hs.add(new StudentJavaBean(21,"赵六",88));

Iterator it=hs.iterator();//获取集合迭代器

while (it.hasNext()) {

System.out.println(it.next());//HashSet不保存元素加入顺序的特征

}

}

}

(2)TreeSet

测试代码(TreeSetTest.java)如下所示:

import java.util.Iterator;

import java.util.Set;

import java.util.TreeSet;

import java.util.*;

public class TreeSetTest {

/** * @param args */

public static void main(String[] args) {

// TODO Auto-generated method stub

Set<StudentJavaBean> ts=new TreeSet<StudentJavaBean>();

StudentJavaBean stu1=new StudentJavaBean(18,"张三",78);

StudentJavaBean stu2=new StudentJavaBean(23,"李四",79);

StudentJavaBean stu3=new StudentJavaBean(32,"王五",80);

StudentJavaBean stu4=new StudentJavaBean(21,"赵六",87);

StudentJavaBean stu5=new StudentJavaBean(18,"黄七",89);

ts.add(stu3);

ts.add(stu4);

ts.add(stu1);

ts.add(stu2);

//ts.add(null);//不可以有null ? 会出错!!

Iterator it=ts.iterator();

while (it.hasNext()) {

System.out.println(it.next());

}

}

}

同时,Student类要实现一个 Comparable接口,

修改之后代码如下:

public class StudentJavaBean implements Comparable {//在实现TreeSetTest中,这里接口是必须的

//public class StudentJavaBean  { 

      private int age;

      private String name;

      private Integer score;

 

  public StudentJavaBean() {  } //无参构造方法

  

      public StudentJavaBean(int age, String name,int score) {

super();

this.age = age;

this.name = name;

this.score=score;

}

//与属性对应的get、set存取方法

  public String getName() {

return name;

  }

  public void setName(String name) {

this.name = name;

}

 public Integer getAge() {

return age;

}

 public void setAge(Integer age) {

this.age = age;

}

 public Integer getScore() {

return score;

}

 

public void setScore(Integer score) {

this.score = score;

}

 //要显示Student的信息,必须重写toString()方法

 public String toString() {

return "StudentJavaBean [age=" + age + ", name=" + name +",score="+ score+ "]";

}

   

//在Java规范要求中,如果用户重写了equals()方法,就一定要重写hashCode()方法

//两个对象进行equals比较时,如果返回true,那么它们的hashCode要求返回相等的值

public int hashCode() {

return age*name.hashCode();

}

    

//HashSet 中加入的对象需要重写hashCode()和equals()方法

public boolean equals(Object o) {

StudentJavaBean s=(StudentJavaBean) o;

return age==s.age && name.equals(s.name);

}

//“让StudentJavaBean类实现Comparable接口”

    //因为要实现 Comparable接口,所以要重写comparaTo(object o)方法

//判断执行comparaTo方法的Student对象与传入的对象按排序的条件相比,

//是大于、小于还是等于传入的对象

public int compareTo(Object o) {

StudentJavaBean s=(StudentJavaBean) o;

if (s.getAge() < this.getAge()) 

return 1;

else if(s.getAge() == this.getAge())

return 0;

else 

return -1;

}

//其实Integer 已经实现了Comparable接口,所以这里的compareTo方法中的代码还可以这样写:

// public int  comparaTo(Object o) {

// StudentJavaBean s=(StudentJavaBean )o;

// return s.age.compareTo(this.age);// }

自定义比较器的代码(SelfTreeSetTest.java)如下:

import java.util.*;

import java.util.Iterator;

import java.util.Set;

import java.util.TreeSet;

import java.util.LinkedHashSet;

import java.util.Comparator;

//学生年龄比较器                     //下面这个借口指明参与比较的两个对象是学生类

class StudentAgeComparator implements Comparator<StudentJavaBean>{

public int compare(StudentJavaBean o1, StudentJavaBean o2) {

// TODO Auto-generated method stub

int i=o2.getAge() - o1.getAge();

return i; }}

//学生成绩比较器  

class StudentScoreComparator implements Comparator<StudentJavaBean> {

public int compare(StudentJavaBean o1, StudentJavaBean o2) {

int i=(int)(o2.getScore() - o1.getScore());

return i; }}

public class SelfTreeSetTest {

public static void main(String[] args) {

// TODO Auto-generated method stub

//创建TreeSet对象时选择比较器

//Set<StudentJavaBean> ts=new TreeSet<StudentJavaBean>(new StudentAgeComparator());

//上面是选择年龄比较器,下面是选择分数比较器

Set<StudentJavaBean> ts=new TreeSet<StudentJavaBean>(new StudentScoreComparator());

StudentJavaBean stu1=new StudentJavaBean(18,"张三",99);

StudentJavaBean stu2=new StudentJavaBean(19,"李四",95);

StudentJavaBean stu3=new StudentJavaBean(20,"王五",90);

StudentJavaBean stu4=new StudentJavaBean(21,"赵六",94);

ts.add(stu3);

ts.add(stu4);

ts.add(stu1);

ts.add(stu2);

Iterator it=ts.iterator();

while (it.hasNext()) {    System.out.println(it.next()); } }}

(3)ArrayList

测试代码( ListDemo.java)如下所示:

import java.awt.List;

import java.util.ArrayList;

import java.util.Collection;

import java.util.Iterator;

public class ListDemo {

/**  * @param args  */

public static void main(String[] args) {

Collection c1=new ArrayList();

c1.add(new Student(20,"张三"));

Student c3=new Student(22,"王五");

c1.add(c3);

c1.add(new Student(19,"黄七"));

System.out.println("c1:"+c1);

Collection c2=new ArrayList();

c2.addAll(c1);//将集合c1添加到c2集合对象中的操作

System.out.println("c2:"+c2);

c2.remove(c3);//删除一个学生

System.out.println("c2:"+c2);

c2.add("hello");//添加

System.out.println("c2:"+c2);

Iterator it=c2.iterator();//下面介绍迭代器接口

while (it.hasNext()) { //用迭代器进行迭代(遍历)操作

Object obj=it.next(); //取出的元素类型为Object类型

System.out.println("Iterator遍历c2 "+obj+"\t");

}

}

}

(4)Stack

测试代码(ThrowAndThrowsDemo.java)如下所示:

import java.util.Stack;

public class StackDemo {

/**  * @param args  */

public static void main(String[] args) {

Stack stk=new Stack();//创建一个空Stack

stk.push(new Student(19,"张三"));

stk.push(new Student(20,"李四"));

stk.push(new Student(22,"王五"));

stk.push(new Student(17,"赵六"));

System.out.println("stk="+stk);

//把Stack当作Vector看待

stk.addElement(new Student(18,"黄七"));

System.out.println("第三个学生是:"+stk.elementAt(2));

System.out.println("移出栈的顺序是:");

while (!stk.empty()) {

System.out.println(stk.pop());

}

}

}

(5)HashMap(“键-值映射对”的方法,此处使用学生的年龄作为键)

测试代码( HashMapDemo.java)如下所示:

import java.util.HashMap;

import java.util.*;

 

public class HashMapDemo {

/**  * @param args  */

public static void main(String[] args) {

HashMap<String,Student> hashmap=new HashMap();

hashmap.put("18", new Student(18,"张三"));//存放对象用put方法

hashmap.put("20", new Student(20,"王五"));

hashmap.put("22", new Student(22,"李四"));

System.out.println("HashMap:"+‘\n‘+hashmap);

    //该函数有其内部的排序方式,事实上是依据哈希算法来排序的。

Set set=hashmap.keySet();//获取全部键,返回类型是Set

 

Iterator iterator=set.iterator();

while (iterator.hasNext()) {

//System.out.println(iterator.next()+"="+hashmap.get(iterator.next())+";");

System.out.println(hashmap.get(iterator.next())+";");

}

}

}

(6)TreeMap

    TreeMap容器类比较特殊,TreeMap内部使用红黑树结构对“键”进行排序存放,所以放入TreeMap中的“键-值”对的“键”必须是可排序的。

测试代码(TreeMapTest.java)如下所示:

import java.util.Iterator;

import java.util.Set;

import java.util.TreeMap;

public class TreeMapTest {

public static void main(String[] args) {

TreeMap treemap=new TreeMap();

treemap.put("18",new Student(18,"张三"));

//指定键值,如果映射以前包含一个此键的映射关系,那么将替换原值

treemap.put("21",new Student(21,"王五"));

treemap.put("19",new Student(19,"赵六"));

System.out.println("\nTreeMap:\n"+treemap);//可以对键排序

System.out.println(treemap.firstKey());//返回第一个键

Set set=treemap.keySet();

Iterator iterator=set.iterator();

while (iterator.hasNext()) {

System.out.println(treemap.get(iterator.next())+";");

} }}

(7)Properties类(实现属性的读取和存放)

Properties类表示了一个持久的属性集,它可保存在流中或从流中加载。属性列表中每个键及其对应值都是一个字符串,它继承自HashTable,也即哈希表。Properties类存放的“键-值”对都是字符串。

测试代码(PropertiesTest.java)如下所示:

import java.io.IOException;

import java.io.InputStream;

import java.util.Properties;

import javax.security.auth.login.Configuration;

 

public class PropertiesTest {

/**  * @param args  */

public static void main(String[] args) {

//获取文件,并读入到输入流

InputStream is=Thread.currentThread().getContextClassLoader()

.getResourceAsStream("Config.properties");

//创建属性级对象

Properties prop=new Properties();

try {

//从流中加载数据

prop.load(is);

} catch (IOException e) {

e.printStackTrace();

}

String name=prop.getProperty("name");

System.out.println("name="+name);

String idString=prop.getProperty("id");

System.out.println("id="+idString); }

}

在此需要创建一个属性文件,命名为:config.properties,放于工程的src目录中。

属性文件内容如下:

#key=value

name=shenxiaolin\u6C88\u6653\u9E9F

id=105032013

4、请问java中有没有优先队列实现类,如果有,请编写程序,演示该类的使用。

优先级队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。PriorityQueue是从JDK1.5开始提供的新的数据结构接口。如果不提供Comparator的话,优先队列中元素默认按自然顺序排列,也就是数字默认是小的在队列头,字符串则按字典序排列。

程序代码如下所示:

import java.util.Comparator;

import java.util.PriorityQueue;

import java.util.Queue;

import java.util.function.Function;

import java.util.function.ToDoubleFunction;

import java.util.function.ToIntFunction;

import java.util.function.ToLongFunction;

public class PriorityQueueTest {

      public static class Student {     //

/**  * @param args */

private int age;

private String name;

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public Student() {

super();

// TODO Auto-generated constructor stub

}

public Student(int age, String name) {

super();

this.age = age;

this.name = name;

}

public String toString() {

return "Student [age=" + age + ", name=" + name + "]";

} }

public static void main(String[] args) {

// TODO Auto-generated method stub

Comparator<Student> OrderIsdn =  new Comparator<Student>(){  

            

public int compare(Student s1, Student s2) {

// TODO Auto-generated method stub

 int age1 = s1.getAge();  

             int age2 = s2.getAge();

                if(age2 > age1)  

                {   return 1; }  

                else if(age2 < age1)  

                {   return -1;}  

                else  

                {   return 0; }  

}

        };  

     PriorityQueue<Student> priorityQueue =  new PriorityQueue<Student>(11,OrderIsdn);  

        Student s1 = new Student(18,"张三");  

        Student s3 = new Student(19,"李四");  

        Student s2 = new Student(17,"王五");  

        priorityQueue.add(s1);  

        priorityQueue.add(s3);  

        priorityQueue.add(s2);  

        while (!priorityQueue.isEmpty()) {

System.out.println(priorityQueue.poll());  

}

    }

}

五、实验总结

1.本次实验按时按量完成。

2.当有多个catch语句,在安排catch语句的顺序时,首先应该捕获子类异常,然后再捕获父类异常。如果顺序弄反了,后面捕获异常的代码将无法被调用。如果异常是同级关系,则无所谓哪个置前,哪个置后。

3.如果有需要使用return语句时,一个合理的做法是,既不在try内部使用return语句,也不在 finally内部使用 return语句,而应该在finally语句之后使用return 来表示函数的结束和返回。

4.一般都需要throw和throws语句的组合使用,就是在捕获异常后,抛出一个明确的异常给调用者。需要注意的是:throw语句是编写在方法之中的,而throws语句是用在方法签名之后的。在同一个方法中使用throw和throws时要注意,throws抛出的类型的异常范围要比throw抛出的对象范围大才可以。

5.Stack类继承自Vector,而Vector又有父类,这样Stack中出现了多余方法。若我们只希望Stack栈完成进栈和出栈功能就行,而不需要add等方法,则可通过LinkedList来完成,因为LinkedList链表结构可以快速地实现插入和删除操作。

6.因为PriorityQueueTest是一个动态的内部类,创建这样的对象必须有实例与之对应,程序是在静态方法中直接调用动态内部类会报错误。这样的错误好比类中的静态方法不能直接调用动态方法。可以把该内部类Student声明为static,或者不要在静态方法中调用。

7.此次实验主要是练习熟悉Java异常处理机制以及Java集合框架和泛型机制。通过编程代码的实践加深对这些知识的理解和巩固。

 

Java 异常处理机制和集合框架

标签:

原文地址:http://www.cnblogs.com/shenxiaolin/p/4927298.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!