本文最后更新于2020年11月15日,已超过 3 个月没更新!

JAVA实验三:掌握泛型类的原理和使用方法。

实验任务书

“实验3说明”文件夹中给出了一些源程序,完成以下要求:其中,StuList.java(假设其中的类实现了接口MyList)中需要补充代码。
要求:
(注意,本次实验要做两个版本。
第一个版本是,排序时树映射的第一个泛型是封装类,测试程序时,会发现这种版本在学生成绩都不相同时是没有问题的,如果有成绩相同的情况,请观察程序的显示结果,看看有什么问题?
第二个版本是,对于第一个版本解决不了的问题,请自己思考,编写第二个版本,使得有成绩相同的情况,也都可以正确显示。)
(1)假设源程序StuList.java中的类实现了接口MyList,创建源程序MyList.java,其中的内容是接口MyList的声明。
(2)在StuList.java中根据要求补充代码。其中,学生信息不再存放在数组中,而是存放在双链表泛型类的对象中;排序时不再使用冒泡法或者选择法排序,而是使用树映射泛型类的对象进行排序输出。
(4)StuList.java,MyList.java,Undergraduate.java,Postgraduate.java和Student.java在同一个包中。Main.java在无名包中。
上述源程序可以完成如下任务:
创建学生链表,使用者根据提示信息,选择从键盘上输入本科生或者研究生的学生信息,将其加入学生链表,添加学生信息,删除学生信息,显示学生信息,按照学生成绩排序等。

解决

第一个版本

项目文件结构

├── src  (源文件夹)
│   ├── students  (包)
│       ├── Student.java  (学生信息类(抽象类))
│       ├── StuList.java  (实现接口 MyList)
│       ├── MyList.java  (接口)
│       ├── Undergraduat.java  (本科生类)
│       └── Postgraduate.java  (研究生类)
│   ├── Main.java (位于无名包下)

Main.java

import student2.*;
import java.util.*;

public class Main
{
    public static void main(String[] args)
    {
        Scanner in=new Scanner(System.in);
        StuList list=new StuList();  //创建学生链表
        int num;
        System.out.println("要创建本科生信息表还是研究生信息表?\nA.本科生\tB.研究生");
        switch(in.next().charAt(0))
        {
        case 'A':
        case 'a':
            System.out.println("请问要输入多少个本科生的信息?");
            num=in.nextInt();
            for(int i=0;i<num;i++)
            {
                System.out.println("请输入第"+(i+1)+"位学生的学号,姓名,数学、计算机成绩:");
                Student t=new Undergraduate(in.nextInt(),in.next(),in.nextDouble(),in.nextDouble());
                list.addStu(t);
            }
            list.addStu(new Undergraduate(1312,"shgd",99,98.5));
            list.addStu(new Undergraduate(1316,"ddsa",89,88.5));
            list.print();
            break;
        case 'B':
        case 'b':
            System.out.println("请问要输入多少个研究生的信息?");
            num=in.nextInt();
            for(int i=0;i<num;i++)
            {
                System.out.println("请输入第"+(i+1)+"位学生的学号,姓名,数学、计算机成绩,导师和研究方向:");
                Student t=new Postgraduate(in.nextInt(),in.next(),in.nextDouble(),in.nextDouble(),in.next(),in.next());
                list.addStu(t);
            }
            list.addStu(new Postgraduate(1312,"shgd",99,98.5,"xyy","os"));
            list.addStu(new Postgraduate(1316,"ddsa",89,88.5,"wcl","rgzn"));
            list.print();
            break;
        default:
            System.out.println("输入错误!!!");
            break;
        }
        System.out.println("是否需要删除某个学生信息?输入y确定,输入其他继续:");
        String words=in.next();
        if(words.equals("Y")||words.equals("y"))
        {
            System.out.println("删除第几个同学?");
            list.removeStu(in.nextInt()); 
            System.out.println("最新的学生信息为:");
            list.print();
            list.sort(1);
            list.sort(2);
            in.close();
        }
        else
        {
            System.out.println("最新的学生信息为:");
            list.print();
            list.sort(1);
            list.sort(2);
            in.close();
        }
    }
}

Student.java

package student2;

public abstract class Student 
{
    int id;
    String name;
    double mathScore;
    double computerScore;

    public Student(int id,String name,double mathScore,double computerScore)
    {
        this.id=id;
        this.name=name;
        this.mathScore=mathScore;
        this.computerScore=computerScore;
    }

    public int getId() 
    {
        return id;
    }

    public void setId(int id) 
    {
        this.id = id;
    }

    public String getName() 
    {
        return name;
    }

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

    public double getMathScore()
    {
        return mathScore;
    }

    public void setMathScore(double mathScore)
    {
        this.mathScore = mathScore;
    }

    public double getComputerScore()
    {
        return computerScore;
    }

    public void setComputerScore(double computerScore)
    {
        this.computerScore = computerScore;
    }

    public abstract void print();

}

StuList.java

package student2;
import java.util.*;

public class StuList implements MyList
{
    LinkedList<Student> list; //使用双链表泛型类对象存储学生信息

    public StuList()
    {
        list=new LinkedList<Student>();
    }

    public int size()
    {
        return list.size();
    }

    public boolean addStu(Student x)  //添加学生信息
    {
        return list.add(x);
    }

    public Student removeStu(int index)  //删除指定位置的学生信息
    {
        return list.remove(index-1);
    }

    public void clear() 
    {      
        list.clear();
    }

    public void sort(int x)   
    {
        TreeMap<Double, Student>stuMap=new TreeMap<Double, Student>();
        Iterator<Student>iter=list.iterator();  
        if(x==1)                //按数学成绩排序
        {
            while(iter.hasNext())
            {
                Student temp=iter.next();
                stuMap.put(temp.getMathScore(),temp);
            }
            System.out.println("数学成绩从低到高排序为:");
        }
        else if(x==2)           //按计算机成绩排序
        {
            while(iter.hasNext())
            {
                Student temp=iter.next();
                stuMap.put(temp.getComputerScore(),temp);
            }
            System.out.println("计算机成绩从低到高排序为:");
        }   
        Collection<Student>collection=stuMap.values();
        iter=collection.iterator();     
        System.out.printf("共有%d名学生,信息如下:%n",stuMap.size());
        while(iter.hasNext())
        {
            Student temp=iter.next();
            temp.print();
        }
    }
    public void print()
    {
        System.out.printf("共有%d名学生,信息如下:%n",list.size());
        Iterator<Student>iter=list.iterator();
        while(iter.hasNext())
        {
            Student temp=iter.next();
            temp.print();
        }
    }       
}

MyList.java

package student2;

interface MyList {
    public int size();
    public boolean addStu(Student x);
    public Student removeStu(int index);
    public void clear();
    public void sort(int x);
    public void print();
}

Undergraduat.java

package student2;

public class Undergraduate extends Student
{
    public Undergraduate(int id,String name,double mathScore,double computerScore)
    {
        super(id,name,mathScore,computerScore);
    }

    public void print()
    {   
        System.out.printf("学号:%8d\t姓名:%8s\t数学成绩:%.1f\t计算机成绩:%.1f%n",getId(),getName(),getMathScore(),getComputerScore());
    }
}

Postgraduate.java

package student2;

public class Postgraduate extends Student
{
    public String tutor;
    public String researchArea;

    public Postgraduate(int id,String name,double mathScore,double computerScore,String tutor,String area)
    {
        super(id,name,mathScore,computerScore);
        this.tutor=tutor;
        this.researchArea=area;
    }
    public void print()
    {
        System.out.printf("学号:%8d\t姓名:%8s\t数学成绩:%.1f\t计算机成绩:%.1f\t导数姓名:%8s\t研究方向:%8s%n",getId(),getName(),getMathScore(),getComputerScore(),getTutor(),getResearchArea());
    }

    public String getTutor()
    {
        return tutor;
    }

    public void setTutor(String tutor)
    {
        this.tutor = tutor;
    }

    public String getResearchArea()
    {
        return researchArea;
    }

    public void setResearchArea(String researchArea)
    {
        this.researchArea = researchArea;
    }

}

第二个版本

  • 只需要改StuList.java

Stulist.java(改)

package student2;
import java.util.*;

class Key implements Comparable<Object>   //新添加的类Key
{ 
    double num=0; 
    Key(double num)
    {
        this.num=num;
    }
    public int compareTo(Object b)
    { 
        Key t=(Key)b;
        if(this.num == t.num)
            return 1;
        else
            return (int)((this.num-t.num)*10);
    }
}

public class StuList implements MyList
{
    LinkedList<Student> list; //使用双链表泛型类对象存储学生信息

    public StuList()
    {
        list=new LinkedList<Student>();
    }

    public int size()
    {
        return list.size();
    }

    public boolean addStu(Student x)  //添加学生信息
    {
        return list.add(x);
    }

    public Student removeStu(int index)  //删除指定位置的学生信息
    {
        return list.remove(index-1);
    }

    public void clear() 
    {      
        list.clear();
    }

    public void sort(int x)   
    {
        //TreeMap<Double, Student>stuMap=new TreeMap<Double, Student>(); //原来
        TreeMap<Key, Student>stuMap=new TreeMap<Key, Student>();   //改后
        Iterator<Student>iter=list.iterator();  
        if(x==1)                //按数学成绩排序
        {
            while(iter.hasNext())
            {
                Student temp=iter.next();
                //stuMap.put(temp.getMathScore(),temp);   //原来
                stuMap.put(new Key(temp.getMathScore()),temp);  //改后
            }
            System.out.println("数学成绩从低到高排序为:");
        }
        else if(x==2)           //按计算机成绩排序
        {
            while(iter.hasNext())
            {
                Student temp=iter.next();
                //stuMap.put(temp.getComputerScore(),temp);  //原来
                stuMap.put(new Key(temp.getComputerScore()),temp);  //改后
            }
            System.out.println("计算机成绩从低到高排序为:");
        }   
        Collection<Student>collection=stuMap.values();
        iter=collection.iterator();     
        System.out.printf("共有%d名学生,信息如下:%n",stuMap.size());
        while(iter.hasNext())
        {
            Student temp=iter.next();
            temp.print();
        }
    }
    public void print()
    {
        System.out.printf("共有%d名学生,信息如下:%n",list.size());
        Iterator<Student>iter=list.iterator();
        while(iter.hasNext())
        {
            Student temp=iter.next();
            temp.print();
        }
    }       
}

实验报告

实验目的

掌握泛型类的原理和使用方法

实验内容

“实验3说明”文件夹中给出了一些源程序,完成以下要求:其中,StuList.java(假设其中的类实现了接口MyList)中需要补充代码。
要求:
(注意,本次实验要做两个版本。
第一个版本是,排序时树映射的第一个泛型是封装类,测试程序时,会发现这种版本在学生成绩都不相同时是没有问题的,如果有成绩相同的情况,请观察程序的显示结果,看看有什么问题?
第二个版本是,对于第一个版本解决不了的问题,请自己思考,编写第二个版本,使得有成绩相同的情况,也都可以正确显示。)
(1)假设源程序StuList.java中的类实现了接口MyList,创建源程序MyList.java,其中的内容是接口MyList的声明。
(2)在StuList.java中根据要求补充代码。其中,学生信息不再存放在数组中,而是存放在双链表泛型类的对象中;排序时不再使用冒泡法或者选择法排序,而是使用树映射泛型类的对象进行排序输出。
(4)StuList.java,MyList.java,Undergraduate.java,Postgraduate.java和Student.java在同一个包中。Main.java在无名包中。
上述源程序可以完成如下任务:
创建学生链表,使用者根据提示信息,选择从键盘上输入本科生或者研究生的学生信息,将其加入学生链表,添加学生信息,删除学生信息,显示学生信息,按照学生成绩排序等。

实验结果

第一个版本

imgbed.cn图床

第二个版本

imgbed.cn图床

实验分析

1、由图可知,第一个版本中,如果出现学生成绩相同的情况下,只会保留一个人的成绩,其他成绩相同的人的成绩都会消失。第二个版本修复了这个问题。
2、用到了LinkedList和TreeMap<K,V>两个泛型类,其中利用LinkedList list = new LinkedList();创建双链表泛型类对象list存储学生信息。
利用Double封装类,通过TreeMap 是按键(学生的成绩)的升序排列。TreeMap<Double,Student>treemap=new TreeMap<Double,Student>()。但当学生成绩出现重复时,让Key类实现Comparable 接口重写CompareTo()方法。
TreeMap<Key,Student> treemap= new TreeMap<Key,Student>();实现重复成绩的学生不会被删除。

3.对Comparable和Comparator接口的区别和用法不太理解。
Comparable 接口(排序接口)仅仅只包括一个函数,定义如下:

  package java.lang;
  import java.util.*;
  public interface Comparable {
      public int compareTo(T o);
  }
  //通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”.
  //Comparator 接口(比较器)仅仅只包括两个函数,定义如下:
  package java.util;
  public interface Comparator {
      int compare(T o1, T o2);
      boolean equals(Object obj);
  }

int compare(T o1, T o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”, 若一个类要实现Comparator接口:它一定要实现compareTo(T o1, T o2) 函数。
即:Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。.而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。Comparable相当于“内部比较器”,而Comparator相当于“外部比较器。

  • 最后由lavender编辑于2020年11月22日下午1:59

疏影横斜水清浅,暗香浮动月黄昏