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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© Robber 中级黑马   /  2016-2-18 18:12  /  2699 人查看  /  5 人回复  /   1 人收藏 转载请遵从CC协议 禁止商业使用本文

package com.itheima;

import java.io.*;
import java.util.*;

/*
* 题目要求:
* 1、有五个学生,每个学生有3门课(语文、数学、英语)的成绩,
* 写一个程序接收从键盘输入学生的信息,输入格式为:name,30,30,30(姓名,三门课成绩)。
* 然后把输入的学生信息按总分从高到低的顺序写入到一个名称"stu.txt"文件中。
* 要求:stu.txt文件的格式要比较直观,打开这个文件,就可以很清楚的看到学生的信息。
*
*
* 结题思路:首先需要一个学生对象(Student),其次我们需要一个容器,来存放这些学生对象。
* 由于需要对学生对象按照成绩总分由高到低来排序,所以我们选择TreeSet。由于学生对象不具有比较性,
* 因此学生对象需要实现一个比较器接口,这里就使用了Comparable接口。学生对象放到容器中后需要保障
* 学生的唯一性,所以学生类必须重写Object类中equals方法来定义自己的区分方法。由于TreeSet放入
* 元素时,会先调用hashCode()方法。与容器中已存在的对象的hashCode作比较,如果相同,就调用一次equals()
* 方法来保障元素的唯一性,否则就不调用equals方法,而直接添加对象了,为了更好的保障元素的唯一性,我们需要覆盖
* hashCode()方法。输入学生信息时,由于输入流的来源是键盘,键盘输入的是字符,所以选用Reader类,为了更加高效,
* 使用BufferedReader类。这个类接受了一个InputStreamReader对象作为构造器参数,而InputStreamReader
* 需要一个InputStream对象作为其构造参数,因此就是用System.in对象,他是InputStream类型,成为"标准"输入流,
* 通常对应的就是键盘输入。把学生信息写入到磁盘文件stu.txt文档中。
*/
class Student implements Comparable<Student> {
        private String name;
        private int math, chinese, english;
        private int sum;

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

        public String getName() {
                return name;
        }

        public int getSum() {
                return sum;
        }

        // 覆盖了默认的hashCode()方法以保证学生的唯一性
        @Override
        public int hashCode() {
                return name.hashCode() + sum * 78;
        }

        @Override
        public boolean equals(Object obj) {
                if (!(obj instanceof Student)) // 判断传入的参数是否为Student类型,不是就会抛出类转型异常
                        throw new ClassCastException("类型不匹配");
                Student s = (Student) obj;
                return this.name.equals(s.name) && this.sum == s.sum; // 比较两个学生对象的姓名和总分数,相同则返回true,否则为false
        }

        // 实现接口所要求的方法,以便按我们所需要的方式排序学生对象
        @Override
        public int compareTo(Student o) {
                int num = new Integer(this.sum).compareTo(new Integer(o.sum)); // 比较两个学生对象的总分数,以便按总分排序
                if (num == 0) // 如果总分数相同,就比较姓名,次要条件就会以姓名排序
                        return this.name.compareTo(o.name);
                return num;
        }

        // 自定义自己的打印学生对象方法
        @Override
        public String toString() {
                return name + ",语文成绩:" + chinese + ",数学成绩:" + math + ",英语成绩:" + english;
        }
}

// 收集学生信息的工具来
class StudentInfoTool {
        public static Set<Student> getStudents() throws NumberFormatException,
                        IOException {
                return getStudents(null);
        }

        // 从键盘获取学生信息,并存入到TreeSet集合中,该方法返回一个包含学生对象的Set集合
        public static Set<Student> getStudents(Comparator<Student> cmp) // 传入一个比较器以便按需排序
                        throws NumberFormatException, IOException { // 为简化代码,就把异常直接抛出了,但实际开发中不能这么做
                // 输入学生的信息,输入格式为:name,30,30,30(姓名,语文,数学,英语三门课成绩)。
                System.out.println("输入学生的信息,输入格式为:name,30,30,30(姓名,语文,数学,英语三门课成绩)。");
                BufferedReader bufr = new BufferedReader(new InputStreamReader(
                                System.in));
                Set<Student> stus = null;
                if (cmp == null)
                        stus = new TreeSet<Student>();
                else
                        stus = new TreeSet<Student>(cmp);
                String line = null;
                while ((line = bufr.readLine()) != null) {
                        if ("".equals(line)) // 输入over就结束输入学生信息
                                break;
                        String[] info = line.split("\\,"); // 把输入的一行数据串按','切割以便获取姓名和各们课成绩数据
                        Student stu = new Student(info[0], Integer.parseInt(info[1]),
                                        Integer.parseInt(info[2]), Integer.parseInt(info[3])); // 把获取的学生信息用来创建一个具体的学生对象
                        stus.add(stu); // 把学生对象添加到集合中
                }
                bufr.close(); // 关闭输入流,释放资源
                return stus;
        }

        // 把存储有学生对象的集合写入到文件中
        public static void write2File(Set<Student> stus, File f) throws IOException {
                BufferedWriter bufw = new BufferedWriter(new FileWriter(f));
                for (Student stu : stus) { // foreach语法
                        bufw.write(stu.toString() + "\t");
                        // bufw.write(stu.getSum() + "");
                        bufw.newLine(); // 写入一个行分隔符
                        bufw.flush(); // 刷新该流的缓冲,即把内存中的数据写入到文件中
                }
                bufw.close();
        }
}

public class Test1 {
        public static void main(String[] args) throws NumberFormatException,
                        IOException {
                // sources为eclipse中java工程目录下的一个文件夹
                File file = new File("stu.txt");

                // 上面Student类实现了Comparable接口后,就会按总分数的自然顺序排序,即从低到高。但题目要求的是从高到低,而Collections的reverseOrder()方法就会强行逆转这个自然顺序,即从高到低了
                Comparator<Student> cmp = Collections.reverseOrder();

                Set<Student> stus = StudentInfoTool.getStudents(cmp); // 传入强行逆转后的比较器
                StudentInfoTool.write2File(stus, file); // 把按总分排序的学生信息写入的文件中
                System.out.println("学生的信息已经写到该项目目录下的stu.txt文档中。");
        }
}

5 个回复

倒序浏览
先收藏一个
回复 使用道具 举报
谢谢分享,哈哈哈哈哈哈
回复 使用道具 举报
不错!!点个赞!
回复 使用道具 举报
好资源!!!
回复 使用道具 举报

好资源!!!zanzanzanazanzanzan
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马