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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© zczcyc0201 中级黑马   /  2012-10-14 16:38  /  3114 人查看  /  5 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

这道题我总感觉我写复杂了,但最终把这个功能实现了,有没有高手帮忙简化一下代码

有五个学生,每个学生有3门课(语文、数学、英语)的成绩,写一个程序接收从键盘输入学生的信息,
输入格式为:name,30,30,30(姓名,三门课成绩),然后把输入的学生信息按总分从高到低的顺序写入到
一个名称"stu.txt"文件中。要求:stu.txt文件的格式要比较直观,打开这个文件,就可以很清楚的看到学生的信息。

public class Test2 {
    //为了便于主体代码的观看,此例中异常做抛出处理,否则代码很长显得很乱,请老师理解
        public static void main(String[] args) throws Exception
        {
                //程序启动后将打印的信息
                System.out.println("开始录入,请输入5位学生的信息,满5位后自动结束,手动结束请输入exit");
                //调用方法,开启键盘录入
            getInfo();
            
            
        }
       
        public static void getInfo()throws Exception
        {
                 //定义一个TreeSet集合用于存储数据,
                 Set<Student> studentSet = new TreeSet<Student>();
               
                 //定义一个字符流缓冲区读取键盘录入
             BufferedReader keyInput = new BufferedReader(new InputStreamReader(System.in));  
             //定义临时标记 记录输入成功的次数
             int tempFlag = 0;
             //循环读取键盘录入
             String line = null;
         while((line=keyInput.readLine())!=null)
         {
                 //定义结束录入条件,输入exit跳出循环录入
                 if("exit".equals(line))
                        {
                         keyInput.close();
                         break;
                        }
                 //定义一个字符串数组,将键盘录入的信息用","分割后存入此数组                 
                 String[] info = line.split(",");
                 
                 //限定分割后的录入信息只能为4部分,即姓名和三门学科的成绩,否则报错
                 if(info.length==4){

             //调用isInt()方法判定录入的成绩是否为0-100的数字(此程序分数按常规考虑,即0-100为有效)
                 if(isInt(info[1]) & isInt(info[2]) & isInt(info[3]))
                 {
                         //将用户录入的信息封装为Student对象,存入Set集合
                         studentSet.add(new Student(info[0],info[1],info[2],info[3]));
                         tempFlag+=1;
                         //提示用户录入成功
                         System.out.println("录入成功:"+"姓名:"+info[0]+"  "+"语文:"+info[1]+"  "+"数学:"+info[3]+"  "+"英语:"+info[2]);
                         //录入成功五次以后 程序退出
                         if(tempFlag>=5){
                                 System.out.println("录入成功 程序结束 请刷新");
                                 break;
                         }

                 }
               
                 else{
                        //如果分数录入不符合规则,报此错误
                        System.out.println("输入错误,成绩请用0-100的数字表示");
                 }}
                 else{
                        //用户信息录入不符合4段的规则,报此错误
                        System.out.println("输入格式错误,请重新填写,输入格式为:name,30,30,30");
                 }
         }
          //定义一个字符输出流,输出到本工程文件夹下的stu.txt中
          File file = new File("stu.txt");
          FileWriter fileOutPut = new FileWriter (file.getAbsolutePath());
          //创建迭代器,迭代set集合
          Iterator<Student> it = studentSet.iterator();
               while(it.hasNext())
                 {
                      //循环将迭代到的对象取出
                        Student s = it.next();
                        //按规定格式将Student对象的信息写入到流
             fileOutPut.write("姓名:"+s.name+"语文成绩:"+s.chineseScore+"数学成绩:"+s.mathScore+"英语成绩:"+s.englishScore+"\r\n" );
                 }
               //刷新流
               fileOutPut.flush();
               //关闭流
               fileOutPut.close();
               //退出程序
               System.exit(1);        
        }
       
        //定义一个验证成绩信息的方法
        public static boolean isInt(String str){
                   //定义两个临时变量
                   boolean tempBoolean ;
                   int tempInt;
                   try{
                           //如果传入的String能转换为int,则将临时标记标为true,否则返回函数false
                           tempInt = Integer.parseInt(str);
                           tempBoolean=true;
                     }catch(Exception e){
                       return false;
                    }
               //在传入的String能转换为int的情况下,即临时标记为true,如果再满足转换后的成绩在0-100之间,则函数返回true
                   if( tempInt>-1 & tempInt<101 & tempBoolean)
                   {
                           return true;
                   }
                   return false;                                  
        }
}



//定义一个学生类,用来封装用户输入的信息,实现Comparable,具有可比性
class Student implements Comparable{
        String name;
        String chineseScore;
        String englishScore;
        String mathScore;
        //构造函数,此对象一旦建立就拥有名字和三门学科的成绩
        Student(String name,String chineseScore,String englishScore,String mathScore)
        {
                this.chineseScore=chineseScore;
                this.englishScore=englishScore;
                this.mathScore=mathScore;
                this.name=name;
        }
        //复写compareTo方法,按总分排序,如果总分一样,就按名字自然排序。
        @Override
        public int compareTo(Object o) {
                // TODO Auto-generated method stub
                Student other = (Student)o;
                //定义总分,将传入的成绩转换为Int相加
                int allScore=Integer.parseInt(this.chineseScore)+Integer.parseInt(this.englishScore)+Integer.parseInt(this.mathScore);
                //定义比较对象的总分,将传入的成绩转换为Int相加
                int otherAllScore=Integer.parseInt(other.chineseScore)+Integer.parseInt(other.englishScore)+Integer.parseInt(other.mathScore);

                //定义比较方法
                if(allScore>otherAllScore)
                    return -1;
            if(allScore==otherAllScore)
            {
                        //如果总分一样按名字自然排序
                            return this.name.compareTo(other.name);
            }
            return 1;       
        }       
}


评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1 很给力!

查看全部评分

5 个回复

倒序浏览
在判断学生信息输入是否符合规范的时候,应该用一个正则表达式来进行匹配,如果不符合规则,则返回重新输入。这样代码会更简单。
还有其实如果能将输入提示信息,分开,比如,先输入name,然后再提示输入该name的数学成绩,等等,这样可以更友好一点。有了这样的提示随便一个人都知道该怎么操作。

评分

参与人数 1技术分 +1 收起 理由
唐志兵 + 1 赞一个!

查看全部评分

回复 使用道具 举报
这道题我总感觉我写复杂了,但最终把这个功能实现了,有没有高手帮忙简化一下代码

有五个学生,每个学生有3门课(语文、数学、英语)的成绩,写一个程序接收从键盘输入学生的信息,
输入格式为:name,30,30,30(姓名,三门课成绩),然后把输入的学生信息按总分从高到低的顺序写入到
一个名称"stu.txt"文件中。要求:stu.txt文件的格式要比较直观,打开这个文件,就可以很清楚的看到学生的信息。

public class Test2 {
    //为了便于主体代码的观看,此例中异常做抛出处理,否则代码很长显得很乱,请老师理解
        public static void main(String[] args) throws Exception
        {
                //程序启动后将打印的信息
                System.out.println("开始录入,请输入5位学生的信息,满5位后自动结束,手动结束请输入exit");
                //调用方法,开启键盘录入
            getInfo();
            
            
        }
        
        public static void getInfo()throws Exception
        {
                 //定义一个TreeSet集合用于存储数据,
                 Set<Student> studentSet = new TreeSet<Student>();
               
                 //定义一个字符流缓冲区读取键盘录入
             BufferedReader keyInput = new BufferedReader(new InputStreamReader(System.in));  
             //定义临时标记 记录输入成功的次数
             int tempFlag = 0;
             //循环读取键盘录入
             String line = null;
         while((line=keyInput.readLine())!=null)
         {
                 //定义结束录入条件,输入exit跳出循环录入
                 if("exit".equals(line))
                        {
                         keyInput.close();
                         break;
                        }
                 //定义一个字符串数组,将键盘录入的信息用","分割后存入此数组                 
                 String[] info = line.split(",");
                 
                 //限定分割后的录入信息只能为4部分,即姓名和三门学科的成绩,否则报错
                 if(info.length==4){

             //调用isInt()方法判定录入的成绩是否为0-100的数字(此程序分数按常规考虑,即0-100为有效)
                 if(isInt(info[1]) & isInt(info[2]) & isInt(info[3]))
                 {
                         //将用户录入的信息封装为Student对象,存入Set集合
                         studentSet.add(new Student(info[0],info[1],info[2],info[3]));
                         tempFlag+=1;
                         //提示用户录入成功
                         System.out.println("录入成功:"+"姓名:"+info[0]+"  "+"语文:"+info[1]+"  "+"数学:"+info[3]+"  "+"英语:"+info[2]);
                         //录入成功五次以后 程序退出
                         if(tempFlag>=5){
                                 System.out.println("录入成功 程序结束 请刷新");
                                 break;
                         }

                 }
               
                 else{
                        //如果分数录入不符合规则,报此错误
                        System.out.println("输入错误,成绩请用0-100的数字表示");
                 }}
                 else{
                        //用户信息录入不符合4段的规则,报此错误
                        System.out.println("输入格式错误,请重新填写,输入格式为:name,30,30,30");
                 }
         }
          //定义一个字符输出流,输出到本工程文件夹下的stu.txt中
          /*File file = new File("stu.txt"); 此句话没必要再独立创建文件 可以省略*/
          FileWriter fileOutPut = new FileWriter ("stu.txt");//这样写法与你上面写法 一样的效果。
                                                                                   // 其实为了效率可以提高,咱可以包装一哈,使用 BufferedWriter 你懂得。
          //创建迭代器,迭代set集合
          Iterator<Student> it = studentSet.iterator();
               while(it.hasNext())
                 {
                      //循环将迭代到的对象取出
                        Student s = it.next();
                        //按规定格式将Student对象的信息写入到流
             fileOutPut.write("姓名:"+s.name+"   语文成绩:"+s.chineseScore+"    数学成绩:"+s.mathScore+"   英语成绩:"+s.englishScore+"\r\n" );
                 }
               //刷新流
               fileOutPut.flush();
               //关闭流
               fileOutPut.close();
               //退出程序
               System.exit(0); //使用break 也行的。      
        }
        
        //定义一个验证成绩信息的方法其实就是为了判断一哈成绩是否输入合法而已 没必要这么复杂啊。
        public static boolean isInt(String str){
                   int  tempInt=0;//初始化一哈
                       try{
                           //如果传入的String能转换为int临时记录一哈就完事了。
                           tempInt = Integer.parseInt(str);
                               }
                      catch(Exception e)
                       {
                       throw new RuntimeException("输入成绩不合法!请重新输入。。。");
                      }
               //在传入的String能转换为int的情况下,即临时标记为true,如果再满足转换后的成绩在0-100之间,则函数返回true
                   if( tempInt>-1 & tempInt<101 & tempBoolean)
                   {
                           return true;
                   }
                          return false;                                 
        }
}



//定义一个学生类,用来封装用户输入的信息,实现Comparable,具有可比性
class Student implements Comparable{
        private  String name;//尽量私有化,你应该懂的
        private  String chineseScore;
        private  String englishScore;
        String mathScore;
        //构造函数,此对象一旦建立就拥有名字和三门学科的成绩
        Student(String name,String chineseScore,String englishScore,String mathScore)
        {
                   //先判断在进行初始化 比较安全,你懂得。
                this.chineseScore=chineseScore;
                this.englishScore=englishScore;
                this.mathScore=mathScore;
                this.name=name;
        }
        //复写compareTo方法,按总分排序,如果总分一样,就按名字自然排序。
        @Override
        public int compareTo(Object o) {
                // TODO Auto-generated method stub
                Student other = (Student)o;
                //定义总分,将传入的成绩转换为Int相加
                int allScore=Integer.parseInt(this.chineseScore+this.englishScore+this.mathScore);//此地方简化,希望你懂得
                //定义比较对象的总分,将传入的成绩转换为Int相加
                int otherAllScore=Integer.parseInt(other.chineseScore+other.englishScore+other.mathScore);//此地方简化,希望你懂得

                //定义比较方法
                if(allScore>otherAllScore)
                    return 1;
            if(allScore==otherAllScore)
            {
                        //如果总分一样按名字自然排序
                            return this.name.compareTo(other.name);
            }
            return -1;        
        }        
}




我的一点建议而已,  请指教。。。。。

评分

参与人数 1技术分 +1 收起 理由
韩军博 + 1

查看全部评分

回复 使用道具 举报
谢谢3楼哈 学到不少东西 有个两个疑问啊
1. System.exit(0); //使用break 也行的。        这个用break不是退出当前循环吗 能结束程序吗

2.                    try{
                           //如果传入的String能转换为int临时记录一哈就完事了。
                           tempInt = Integer.parseInt(str);
                               }
                      catch(Exception e)
                       {
                       throw new RuntimeException("输入成绩不合法!请重新输入。。。");
                      }
这里如果抛RuntimeException的话不是程序就直接结束了吗
就只能再从新运行了吧?
回复 使用道具 举报
本帖最后由 杨华东 于 2012-10-14 19:54 编辑
zczcyc0201 发表于 2012-10-14 18:45
谢谢3楼哈 学到不少东西 有个两个疑问啊
1. System.exit(0); //使用break 也行的。        这个用break不 ...


1,不好意思啊兄弟,看错了 break 只可以跳出循环包括for嵌套while语句i switch语句 等等。
System.exit(0) 比break 要狠一点!!直接把虚拟机关了。有时候没必要关虚拟机。
   这句话可以不用写!!我觉得

2,你要是想使用标记 没必要用异常处理  直接 返回就行了。
      标记初始化一般为true(随便你都可以)
              满足条件1 变为false
                  满足条件2 变为true

    抛出了运行时异常 程序肯定结束了,只能重新来一遍


不过兄弟  我下次给你完整的 我写的代码   用正则 估计简单点    一起加油啊
黑马等着我们呢   嘿嘿
回复 使用道具 举报
刚开始学看不懂
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马