A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 宗士为 中级黑马   /  2012-5-14 19:42  /  2534 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

程序的需求是:从命令行输入学生的名字,数学语文英语成绩,还有总分   根据总分对学生进行排名
                         如果总分不同  按总分排名
                         如果总分相同 姓名不同则按哈希码值对名字进行排序
                          并在输出文件中输出结果

但是输出文件打不出结果    求解

public class Exercise5 {

        public static void main(String[] args) throws IOException {
                BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                Set<Student> set = new TreeSet<Student>();
                for(;;) {
                        String line = in.readLine();
                        if("qult".equals(line)) {
                                in = new BufferedReader(new FileReader("student.txt"));
                                continue;
                        }else if(line == null) {
                                in.close();
                                break;
                        }
                        String[]arr = line.split(",");
                        Student stu = new Student(arr[0] + Integer.parseInt(arr[1])+ Integer.parseInt(arr[2])+ Integer.parseInt(arr[3]));
                        set.add(stu);
                }
               
                PrintStream out = new PrintStream(new FileOutputStream("student.txt"));
                System.setOut(out);
                for(Student s : set)
                        System.out.println(s);
                out.close();
        }
}

public class Student implements Comparator<Student> {
        private String name;
        private int math;
        private int chinese;
        private int english;
        private int num;
       
        public Student(String name) {
                super();
                this.name = name;
                this.math = math;
                this.chinese = chinese;
                this.english = english;
                num = math + chinese + english;
        }

        public String toString() {
                return  name + "," + math + ","+ chinese + "," + english;
        }
        public int compare(Student o1, Student o2) {
                int numGap = o1.math - o2.math;
                int nameGap = o1.name.compareTo(o2.name);
                return numGap != 0 ? numGap : nameGap;
        }
}




评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1 哥们元素自身比较和比较器的用法没搞清楚哦.

查看全部评分

5 个回复

倒序浏览
类的自然排序要实现Comparable接口,不是Comparator接口,Comparator是自己定义比较器往集合中作为参数传递的。

评分

参与人数 1技术分 +1 收起 理由
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
看了一下你的程序,出现问题的地方很多,对于集合的内容好像还没有掌握。import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Set;
import java.util.TreeSet;

/*
* 程序的需求是:从命令行输入学生的名字,数学语文英语成绩,
* 格式为zhangsan,89,78,78
*    根据总分对学生进行排名
如果总分不同  按总分排名
如果总分相同 姓名不同则按哈希码值对名字进行排序
并在输出文件中输出结果

*/
public class StudentSortDemo {

        /**
         * @param args
         */
        public static void main(String[] args) {
                BufferedReader br = null;

                try {
                        br = new BufferedReader(new InputStreamReader(System.in));
                        String line = null;
                        Set<Students> set = new TreeSet<Students>();
                        while ((line = br.readLine()) != null) {
                                if ("over".equals(line))
                                        break;
                                String[] stuinfo = line.split(",");                       
                                Students s = new Students(stuinfo[0],
                                                Integer.parseInt(stuinfo[1]),
                                                Integer.parseInt(stuinfo[2]),
                                                Integer.parseInt(stuinfo[3]));
                                set.add(s);
                        }
                        PrintWriter pw = new PrintWriter(System.out,true);//定义一个打印流,将输出打印到控制台
                       
                        for(Students s : set){
                                pw.println(s.toString());
                                //pw.println(s.getSum());
                        }


                } catch (IOException e) {
                        e.printStackTrace();
                } finally {
                        if(br !=null)
                                try {
                                        br.close();
                                } catch (IOException e) {
                                        e.printStackTrace();
                                }
                }
        }

}

/*
* 定义一个学生类,实现Comparable接口,使其就有比较性
* 要比较,就要实现equals方法和hashcode方法。
*/
class Students implements Comparable<Students> {

        private String name;
        private int chinese;
        private int math;
        private int english;
        private int sum;

        public Students(String name, int chinese, int math, int english) {
                this.name = name;
                this.chinese = chinese;
                this.math = math;
                this.english = english;
                this.sum = chinese + math + english;
        }

        public String getName() {
                return name;
        }

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

        public int getChinese() {
                return chinese;
        }

        public void setChanese(int chinese) {
                this.chinese = chinese;
        }

        public int getMath() {
                return math;
        }

        public void setMath(int math) {
                this.math = math;
        }

        public int getEnglish() {
                return english;
        }

        public void setEnglish(int english) {
                this.english = english;
        }

        public int getSum() {
                return sum;
        }

        public void setSum(int sum) {
                this.sum = sum;
        }

        public int hashCode() {
                return this.name.hashCode() + this.sum % 2*7;
        }

        public boolean equals(Object obj) {
                if (obj instanceof Students)
                        throw new RuntimeException("类型匹配");
                Students stu = (Students) obj;

                return this.name.equals(stu.name);
        }

        public String toString() {
                return name + "[" + chinese + "," + math + "," + english + "]"
                                + "   " + sum;
        }

        /*
         * 复写比较方法,如果学生的总成绩相等,则按学生姓名的自然循序排序
         */
        public int compareTo(Students o) {
                int num = new Integer(this.sum).compareTo(new Integer(o.sum));
                if (num == 0)
                        return this.name.compareTo(o.name);
                return num;
        }

}给一个我刚写的程序。你可以对照的看下

评分

参与人数 2技术分 +1 黑马币 +5 收起 理由
秦超 + 5 虽然我写的有些和你不一样,但是你的代码给.
贠(yun)靖 + 1

查看全部评分

回复 使用道具 举报
陈忠 发表于 2012-5-14 21:44
看了一下你的程序,出现问题的地方很多,对于集合的内容好像还没有掌握。import java.io.BufferedReader;
i ...

给了我一些启示!谢了
回复 使用道具 举报
首先,上面几位都说明了这个代码里面的错误,要实现Comparable接口而不是Copmarator,你把比较器和可比较性弄混了,这个就不着重说了。我想说的是如果现在学生里面有两个同名同姓的学生考了同样的分数,上面各位的代码都只能存入一个,这是由于TreeSet不能有重复元素的特性所决定的。这样就有了遗漏,当然,你可以在重写compareTo方法的时候这样写:
public int compareTo(Student o) {
      int sumGap = o.sum - this.sum;
      int nameGap = this.name.compareTo(o.name);
      return sumGap != 0 ? sumGap : (nameGap != 0 ? nameGap : 1);
}
但是这样的话会违背排序原则,虽然结果是正确的,但是不太合乎排序原则。在这种需要排序且需要有重复元素的情况下,最好用List来做,然后调用Collections.sort();当然也是需要Student类继承Comparable接口的,重写的时候直接返回sumGap != 0 ? sumGap : nameGap ;这种做法符合排序原则,且不会像TreeSet那样占有较多内存。
回复 使用道具 举报
上面说的排序原则是指排序的稳定性(在判断一个排序的好与坏时,稳定性是很重要的),就是两个完全相同的学生对象在排序之前谁在谁的前面,排序之后还得保证谁在谁的前面,因为虽然两个学生对象的各个属性都是一样的,但是其实是两个对象,他们的内存地址值是不同的。用TreeSet来做的话会出现有可能不稳定的情况。上面返回1的位置只要不是0的数都可以的,但是返回正数和负数的结果是不一样的,也就是说一种是稳定的一种是不稳定的,这就需要我们额外的去判断一些东西。而既然已经有了Collections.sort()方法提供给我们用(可以保证排序的稳定性),那我们何必要再去额外做一些判断来保证这个稳定性呢?所以推荐用List来做需要重复的排序。要去重的排序再用TreeSet来做。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马