java 6-异常

题目

实验目的

掌握常用异常的处理方法;掌握常用集合的基本用法;理解泛型及其应用。

实验要求

独立完成实验,并撰写实验报告。

实验内容

  1. 使用异常机制处理程序错误
    为下面的代码加入适当的异常处理, 使得该程序可以处理输入的字符串不为数字字符串的情况(要求重新输入,最后得到3个从键盘输入的浮点数)。

    public static void main(String[] args) {
    	double[] x = new double[3];double sum = 0.0;
    	Scanner inputScan = new Scanner(System.in);
    	for(int i = 0; i < x.length;i++){
    		System.out.println("Please input the "+(i+1)+" number:");
    		String input = inputScan.nextLine();
    		x[i] = Double.parseDouble(input);
    		sum += x[i];
    	}
    	System.out.println(Arrays.toString(x));
    	System.out.println("Sum:" + sum);
    }
    
  2. List与Iterator接口
    (1)编写NameDao接口,包含如下方法:

    //将数组中的字符串放入列表,该方法需要使用ListIterator接口实现添加
    public List getNameFromArray(String[] names);
    //在列表中搜索到与name相同的项目,就返回该name所在的序号,找不到返回-1。
    public int searchName(List nameList, String name);
    //根据指定id,从列表中移除指定的项目,如果id指定错误(负数或者超出列表最大值)抛出IllegalArgumentException异常,移除成功返回true
    public boolean removeFromList(List nameList, int id);
    

    (2)编写NameDaoImpl实现NameDao接口。
    (3)编写一个测试类,测试上述代码的功能。

  3. Map与HashMap

    • (1)编写Student类,只有String name与int age两个属性和他们的setter/getter方法,覆盖其hashCode与equals方法。
    • (2)在Util类中编写方法:List getRandomStudents(int n)随机生成n个学生的列表。
      说明:调用“基础代码”中的Util.getRandomName (int min, int max)获取随机名字,调用public static int getRandomAge(int min, int max)生成随机年龄。
    • (3)在Util类中编写方法:public static Map<string, student=“”> makeStudentMap(List);,将List中每个Student的name作为key, Student对象本身作为value放入Map中,并返回。
    • (4)在Util类中编写方法:public static String searchName(List nameList, String name);,根据指定的name返回相应的字符串,如果没有找到返回null。
    • (5)在Util类中编写方法:public static Student searchStudent(Map<string,student> stuMap, String name);,根据指定的name返回对应的学生,如果没有找到返回null。
    • (6)在Util类中编写方法:public static List generateNameList(int n);,生成n个字符串的NameList并返回。
    • (7)在Util类中编写方法:Map<string, student=“”> generateStudentMap(int n);,生成包含n个键的的StudentMap并返回。
      说明:调用getRandomStudents方法;调用makeStudentMap方法;返回StudentMap。
    • (8)对比测试。在初始化阶段调用generateNameList方法生成nameList列表,里边包含1000万个字符串。在初始化阶段调用getRandomStudents生成1000万个Student对象,然后调用makeStudentMap方法生成stuMap映射表。
      对nameList调用searchName方法搜索指定字符串并统计执行时间。
      对stuMap调用searchStudent方法搜索指定字符串对应的学生对象并统计执行时间。
      思考:步骤(8)中,哪个方法搜索速度快?为什么?
    • (9)遍历输出StudentMap前10个的key,前10个value,前10个entry。

备注:可以设置虚拟机选项,让JVM能够拥有大内存。
★Eclipse中的设置方法:打开Window->Preferences菜单,左边列选择Java->Installed JREs,在需要设置的JRE上,点击Edit,设置Default VM arguments的值为“-Xms1024m -Xmx4096m”,其中-Xms设置最小内存,-Xmx设置最大内存。
★IDEA中的设置方法:选择Help->Edit Custom VM Options,修改-Xms和-Xmx为相应的内存值,如-Xms1024m、-Xmx4096m。

  1. Collections
    • (1)改写Student类,增加int grade属性。
    • (2)随机生成100个Student对象放入students数组。
    • (3)将students数组转换成studentList(List类型)。
    • (4)使用Collections.sort对student的成绩进行排序。
    • (5)使用Collections的min和max方法找到成绩最高的和成绩最低学生。
    • (6)使用Collections的binarySearch查找成绩等于60的学生。
    • (7)编写方法从studentList找出grade小于60的学生,放入otherList。
    • (8)使用List的removeAll方法,从studentList中移除otherList。
    • (9)使用Collections的shuffle方法,打乱studentList中学生排列的顺序。
    • (10)将studentList转换为数组。

参考资料

Student.java

package collectionTest;

public class Student{

	private String name;
	private int age;

	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + age;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}
	@Override
	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 (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
}

Util.java

package collectionTest;

import java.util.Random;
import java.util.Set;
import java.util.TreeSet;

public class Util {

	/**
	 *
	 * @param
	 * @return 返回分布在[0,upLimit]的随机整数
	 */
	public static int getRandomNumber(int upLimit) {
		return new Random().nextInt(upLimit+1);
	}

	/**
	 *
	 * @param min
	 * @param max
	 * @return 返回分布在[min,max]的随机整数
	 */
	public static int getRandomNumber(int min,int max){
		if(min > max){
			throw new IllegalArgumentException("min ="+min+">"+ "max="+max);
		}
		return min + new Random().nextInt(max+1-min);
	}

	/**
	 *
	 * @param min
	 * @param max
	 * @return 返回长度在min到max之间随机名字
	 */
	public static String getRandomName(int min, int max){
		StringBuilder sb = new StringBuilder();

		int n = getRandomNumber(min, max);

		while (n>0) {
			sb.append((char)getRandomNumber('a','z'));
			n--;
		}
		return sb.toString();
	}
}

实验报告

一、目的

掌握常用异常的处理方法;
掌握常用集合的基本用法;
理解泛型及其应用。

二、实验内容与设计思想

1.设计思路

(1) 使用异常机制处理程序错误

(2) List与Iterator接口

(3) Map与HashMap

(4) Collections

主要数据结构
问题三
public class Student
{
String name;
int age;
}
学生类,包含名字与年龄属性
问题四
public class Student2
{
    String name;
    int age;
    int grade;
}
改良的学生类,包含名字、年龄与成绩属性
主要代码结构

三、实验使用环境

软件:java version “18.0.2”,EclipseIDE 2022-06

平台:win10

四、实验步骤和调试过程

exp1:使用异常机制处理程序错误

需求

加入适当的异常处理,
使得该程序可以处理输入的字符串不为数字字符串的情况(要求重新输入,最后得到3个从键盘输入的浮点数)。

实验步骤

Error类

package exp1;

import java.util.Arrays;
import java.util.Scanner;

public class Error
{
    public static void main(String[] args) {
        double[] x = new double[3];
        double sum = 0.0;
        Scanner inputScan = new Scanner(System.in);
        for(int i = 0; i < x.length;i++){
            System.out.println("Please input the "+(i+1)+" number:");
            String input = inputScan.nextLine();
            try
            {
                x[i] = Double.parseDouble(input);
            }
            catch (Exception e)
            {
                e.printStackTrace();
                System.out.println("输入的不是数字,请重新输入");
                i--;
                continue;
            }
            sum += x[i];
        }
        System.out.println(Arrays.toString(x));
        System.out.println("Sum:" + sum);
    }
}

测试数据设计

输入三个数字,其中夹杂错误输入字母或符号

测试结果分析

exp2:List与Iterator接口

需求

(1)编写NameDao接口,包含如下方法:

**public List getNameFromArray(String\[\] names);**
//在列表中搜索到与name相同的项目,就返回该name所在的序号,找不到返回-1。
public int searchName(List nameList, String name);**
//根据指定id,从列表中移除指定的项目,如果id指定错误(负数或者超出列表最大值)抛出IllegalArgumentException异常,移除成功返回true
public boolean removeFromList(List nameList, int id);

(2)编写NameDaoImpl实现NameDao接口。

(3)编写一个测试类,测试上述代码的功能。

实验步骤

NameDao接口

package exp2;

import java.util.List;

public interface NameDao
{
    public List getNameFromArray(String[] names);
    public int searchName(List nameList, String name);
    public boolean removeFromList(List nameList, int id) throws Exception;
}

NameDaoImpl类

package exp2;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.ListIterator;

public class NameDaoImpl implements NameDao
{
    public List getNameFromArray(String[] names)
    {
        List nameList = new ArrayList();
        ListIterator li = nameList.listIterator();
        for(String name:names)
            li.add(name);
        return nameList;
    }

    public int searchName(List nameList, String name)
    {
        return nameList.indexOf(name);
    }

    public boolean removeFromList(List nameList, int id) throws Exception
    {
        if(id>=0&&id<nameList.size())
        {
            nameList.remove(id);
            return true;
        }
        else
        {
            try
            {
                throw new IllegalArgumentException();
            }
            catch (IllegalArgumentException e2)
            {
                System.out.println("Catch an IllegalArgumentException..."+e2.getMessage()+",不存在这个id");
                return false;
            }
        }
    }
}

Test类

package exp2;

import java.util.List;

public class Test
{
    public static void main(String[] args) throws Exception
    {
        NameDao nameDao = new NameDaoImpl();

        String[] names = new String[]{"张三", "李四", "王五"};
        List list = nameDao.getNameFromArray(names);

        int index = nameDao.searchName(list,"张三");
        if(index!=-1)
            System.out.println("找到了,位置在"+index);
        else
            System.out.println("没有这个名字");

        index = nameDao.searchName(list,"孙六");
        if(index!=-1)
            System.out.println("找到了,位置在"+index);
        else
            System.out.println("没有这个名字");

        boolean isRemove = nameDao.removeFromList(list,0);
        if(isRemove)
            System.out.println("删除成功");

        isRemove = nameDao.removeFromList(list,5);
        if(isRemove)
            System.out.println("删除成功");
    }
}

测试数据设计

使用一个数组:测试getNameFromArray功能

测试searchName功能:使用存在和不存在的序号进行测试

测试removeFromList功能:使用存在和不存在的id进行测试

测试结果分析

exp3:Map与HashMap

需求

(1)编写Student类,只有String name与int
age两个属性和他们的setter/getter方法,覆盖其hashCode与equals方法。

(2)在Util类中编写方法:List getRandomStudents(int
n)随机生成n个学生的列表。

说明:调用"基础代码"中的Util.getRandomName (int min, int
max)获取随机名字,调用public static int getRandomAge(int min, int
max)生成随机年龄。

(3)在Util类中编写方法:public static Map<string,
student=“”> makeStudentMap(List);,将List中每个Student的name作为key,
Student对象本身作为value放入Map中,并返回。

(4)在Util类中编写方法:public static String searchName(List nameList,
String name);,根据指定的name返回相应的字符串,如果没有找到返回null。

(5)在Util类中编写方法:public static Student
searchStudent(Map<string,student> stuMap, String
name);,根据指定的name返回对应的学生,如果没有找到返回null。

(6)在Util类中编写方法:public static List generateNameList(int
n);,生成n个字符串的NameList并返回。

(7)在Util类中编写方法:Map<string,
student=“”> generateStudentMap(int
n);,生成包含n个键的的StudentMap并返回。

说明:调用getRandomStudents方法;调用makeStudentMap方法;返回StudentMap。

(8)对比测试。在初始化阶段调用generateNameList方法生成nameList列表,里边包含1000万个字符串。在初始化阶段调用getRandomStudents生成1000万个Student对象,然后调用makeStudentMap方法生成stuMap映射表。

对nameList调用searchName方法搜索指定字符串并统计执行时间。

对stuMap调用searchStudent方法搜索指定字符串对应的学生对象并统计执行时间。

思考:步骤(8)中,哪个方法搜索速度快?为什么?

(9)遍历输出StudentMap前10个的key,前10个value,前10个entry。

实验步骤

Student类

package exp3;

import java.util.Objects;

public class Student{

    private String name;
    private int age;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    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 (age != other.getAge())
            return false;
        if (name == null) {
            if (other.getName() != null)
                return false;
        } else if (!name.equals(other.getName()))
            return false;
        return true;
    }
    public Student(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
}

Util类

package exp3;

import com.sun.jdi.PathSearchingVirtualMachine;

import java.util.*;

public class Util
{
    //随机生成n个学生的列表
    public static List<Student> getRandomStudents(int n)
    {
        List<Student>students = new ArrayList<>();
        for(int i=0;i<n;i++)
            students.add(new Student(getRandomName(3,7),getRandomNumber(18,27)));
        return students;
    }

    //将List中每个Student的name作为key, Student对象本身作为value放入Map中,并返回。
    public static Map<String, Student> makeStudentMap(List<Student> students)
    {
        Map<String,Student>studentMap = new HashMap<>();
        for(Student student:students)
            studentMap.put(student.getName(),student);
        return studentMap;
    }

    //根据指定的name返回相应的字符串,如果没有找到返回null
    public static String searchName(List<String> nameList, String name)
    {
        int index = nameList.indexOf(name);
        if(index==-1)
            return null;
        return nameList.get(index);
    }

    //生成n个字符串的NameList并返回
    public static List<String> generateNameList(int n)
    {
        List<String>nameList = new ArrayList<>();
        for(int i=0;i<n;i++)
        {
            nameList.add(getRandomName(3,7));
        }
        return nameList;
    }

    public static Map<String, Student> generateStudentMap(int n)
    {
        List<Student> students = getRandomStudents(n);
        return makeStudentMap(students);
    }

    public static Student searchStudent(Map<String, Student>studentMap,String name)
    {
        return studentMap.get(name);
    }


     //返回分布在[0,upLimit]的随机整数
    public static int getRandomNumber(int upLimit) {
        return new Random().nextInt(upLimit+1);
    }

    //返回分布在[min,max]的随机整数
    public static int getRandomNumber(int min,int max){
        if(min > max){
            throw new IllegalArgumentException("min ="+min+">"+ "max="+max);
        }
        return min + new Random().nextInt(max+1-min);
    }

    //返回长度在min到max之间随机名字
    public static String getRandomName(int min, int max){
        StringBuilder sb = new StringBuilder();

        int n = getRandomNumber(min, max);

        while (n>0) {
            sb.append((char)getRandomNumber('a','z'));
            n--;
        }
        return sb.toString();
    }
}

Test类

package exp3;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import static exp3.Util.*;

public class Test
{
    public static void main(String[] args)
    {
        //对比测试
        List<String> names = generateNameList(10000);
        List<Student> students = getRandomStudents(10000);
        Map<String,Student> studentMap = makeStudentMap(students);

        long startTime=System.nanoTime();   //获取开始时间
        String name = searchName(names,names.get(5000));
        long endTime=System.nanoTime(); //获取结束时间
        System.out.println("searchName程序运行时间: "+(endTime-startTime)+"ns");

        startTime=System.nanoTime();   //获取开始时间
        Student student = searchStudent(studentMap,name);
        endTime=System.nanoTime(); //获取结束时间
        System.out.println("searchStudent程序运行时间: "+(endTime-startTime)+"ns");

        System.out.println();

        //遍历输出
        int i = 0;
        for(Entry entry:studentMap.entrySet())
        {
            if(++i>10)
                break;
            System.out.println(entry.getKey());
            System.out.println(entry.getValue());
            System.out.println(entry);
            System.out.println();
        }
    }
}

测试数据设计

设计对比测试,测试searchName和searchStudent的执行时间。

输出StudentMap前10个的key,前10个value,前10个entry。

测试结果分析

searchName程序运行时间: 713500ns
searchStudent程序运行时间: 8700ns

107104114102103
exp3.Student@9543d901
107104114102103=exp3.Student@9543d901

112110115
exp3.Student@e38ce822
112110115=exp3.Student@e38ce822

110110122117113
exp3.Student@3cab0166
110110122117113=exp3.Student@3cab0166

112110118
exp3.Student@e38ce880
112110118=exp3.Student@e38ce880

121105108122121
exp3.Student@a156a381
121105108122121=exp3.Student@a156a381

112109121
exp3.Student@e256e64e
112109121=exp3.Student@e256e64e

99102105119102
exp3.Student@b58639
99102105119102=exp3.Student@b58639

118112121117
exp3.Student@976bd894
118112121117=exp3.Student@976bd894

122120118104
exp3.Student@e4f12a7a
122120118104=exp3.Student@e4f12a7a

109119106108119
exp3.Student@84fb0b9f
109119106108119=exp3.Student@84fb0b9f
exp4:Collections

需求

(1)改写Student类,增加int grade属性。

(2)随机生成100个Student对象放入students数组。

(3)将students数组转换成studentList(List类型)。

(4)使用Collections.sort对student的成绩进行排序。

(5)使用Collections的min和max方法找到成绩最高的和成绩最低学生。

(6)使用Collections的binarySearch查找成绩等于60的学生。

(7)编写方法从studentList找出grade小于60的学生,放入otherList。

(8)使用List的removeAll方法,从studentList中移除otherList。

(9)使用Collections的shuffle方法,打乱studentList中学生排列的顺序。

(10)将studentList转换为数组。

实验步骤

Student2类

package exp4;

import java.util.Objects;

public class Student2
{
    String name;
    int age;
    int grade;

    public Student2(String name, int age, int grade)
    {
        this.name = name;
        this.age = age;
        this.grade = grade;
    }

    public String getName()
    {
        return name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public int getAge()
    {
        return age;
    }

    public void setAge(int age)
    {
        this.age = age;
    }

    public int getGrade()
    {
        return grade;
    }

    public void setGrade(int grade)
    {
        this.grade = grade;
    }

    @Override
    public boolean equals(Object o)
    {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student2 student2 = (Student2) o;
        return age == student2.age && grade == student2.grade && Objects.equals(name, student2.name);
    }

    @Override
    public int hashCode()
    {
        return Objects.hash(name, age, grade);
    }
}

Test类

package exp4;

import java.util.*;

public class Test
{
    //返回分布在[0,upLimit]的随机整数
    public static int getRandomNumber(int upLimit) {
        return new Random().nextInt(upLimit+1);
    }

    //返回分布在[min,max]的随机整数
    public static int getRandomNumber(int min,int max){
        if(min > max){
            throw new IllegalArgumentException("min ="+min+">"+ "max="+max);
        }
        return min + new Random().nextInt(max+1-min);
    }

    //返回长度在min到max之间随机名字
    public static String getRandomName(int min, int max){
        StringBuilder sb = new StringBuilder();

        int n = getRandomNumber(min, max);

        while (n>0) {
            sb.append((char)getRandomNumber('a','z'));
            n--;
        }
        return sb.toString();
    }

    //随机生成n个学生的列表
    public static Student2[] getRandomStudent2s(int n)
    {
        Student2[] student2s = new Student2[n];
        for(int i=0;i<n;i++)
            student2s[i] = new Student2(getRandomName(3,7),getRandomNumber(10,50),getRandomNumber(0,100));
        return student2s;
    }

    //将students数组转换成studentList(List类型)
    public static List<Student2> makeStudentList(Student2[] students)
    {
        List<Student2> student2List = new ArrayList<>();
        Collections.addAll(student2List,students);
        return student2List;
    }

    public static void main(String[] args)
    {
        Student2[] student = getRandomStudent2s(100);
        List<Student2> studentList = makeStudentList(student);

        Collections.sort(studentList, (Student2 o1, Student2 o2)->o1.getGrade()-o2.getGrade());

        System.out.println("成绩最高的学生为:"+Collections.min(studentList,(Student2 o1, Student2 o2)->o1.getGrade()-o2.getGrade()).getName());
        System.out.println("成绩最低的学生为:"+Collections.max(studentList,(Student2 o1, Student2 o2)->o1.getGrade()-o2.getGrade()).getName());
        int index = Collections.binarySearch(studentList,new Student2("",0,60),(Student2 o1,Student2 o2)->o1.getGrade()-o2.getGrade());
        if (index>=0)
            System.out.println("成绩等于60的学生为"+studentList.get(index).getName());
        else
            System.out.println("没有成绩等于60的学生");

        List<Student2> otherList  = getDisqualifiedStudent(studentList);
        studentList.removeAll(otherList);
        Collections.shuffle(studentList);
        Student2[] studentsArr = makeStudentArray(studentList);
    }

    public static List<Student2> getDisqualifiedStudent(List<Student2> studentList)
    {
        List<Student2> otherList = new ArrayList<>();
        for(Student2 student2:studentList)
            if(student2.getGrade()<60)
                otherList.add(student2);
        return otherList;
    }

    public static Student2[] makeStudentArray(List<Student2> student2List)
    {
        return (Student2[]) student2List.toArray(new Student2[student2List.size()]);
    }
}

测试数据设计

测试生成100个学生到数组

测试数组转List

测试List转数组

测试寻找成绩最高,最低和等于60的学生

测试removeAll和shuffle功能

测试结果分析

五、实验小结

实验中遇到的问题及解决过程

实验中产生的错误及原因分析

实验体会和收获。

掌握了常用异常的处理方法;

掌握了常用集合的基本用法;

理解了泛型及其应用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值