package com.JiHeTotal;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeMap;
public class TestStudent {
public static void main(String[] args) {
List<Student> list = new ArrayList<Student>();// 存储学生信息的学生容器
Map<String, Map<String, Double>> map2 = new HashMap<String, Map<String, Double>>();// 人名和学科、分数的映射
Map<String, Double> map3 = new TreeMap<String, Double>();// 总分和人名的映射(这个地方有点问题就是当总分相同时会发生数据丢失,处理方式是重新定义比较器)
Scanner in = new Scanner(System.in);
try {
// 把学生信息加载到List中
PushScodeToList(list);
// 总分 // 个人成绩单
totalScode(list, map2, map3);
// 生成总分排名文件
List<Map.Entry<String, Double>> list1 = ArrangTotalScode(map3);
// 生成班级最高分和最低分的同学的成绩单文件
High_Lower_Scode_File(list, list1);
// 生成单科的排名文件(需要输入要生成哪一科)
System.out.println("请输入你要生成排名文件的科目");
String subjectName = in.next();
Per_Subject_ScodeFile(list, subjectName);
// 统计及格人数和不及格人数
System.out.println("请输入你要统计及格人数的科目名:");
String name = in.next();
getPersonNumber(list, name);
} catch (IOException e) {
e.printStackTrace();
}
}
/*
*
*
* 用来统计及格人数和不及格人数
*
*/
private static void getPersonNumber(List<Student> list, String name) throws IOException {
Iterator<Student> it = list.iterator();// 创建学生对象的容器
int i = 0;// 统计及格人数
StringBuffer sb = null;
BufferedWriter bw = null;
try {
sb = new StringBuffer();
bw = new BufferedWriter(new FileWriter("e:\\getPersonNumber.txt", true));
while (it.hasNext()) {
Student student = (Student) it.next();
Set<Map.Entry<String, Double>> setMap = student.scode.entrySet();
Iterator<Map.Entry<String, Double>> it1 = setMap.iterator();
while (it1.hasNext()) {
Map.Entry<String, Double> entry = (Map.Entry<String, Double>) it1.next();
if (entry.getKey().contains(name) && entry.getValue() >= 60) {
i++;
}
}
}
System.out.println(name + "及格人数:" + "\t" + (i) + "\t" + "不及格人数:" + (list.size() - i));
sb.append(name + "及格人数:" + "\t" + (i) + "\t" + "不及格人数:" + (list.size() - i));
bw.write(sb.toString());
bw.newLine();
bw.flush();
} finally {
if (bw != null) {
bw.close();
}
}
}
/*
*
*
* 生成单科的排名文件(需要输入要生成哪一科)
*
*
*/
private static void Per_Subject_ScodeFile(List<Student> list, String subjectName) throws IOException {
Map<String, Double> map = new TreeMap<String, Double>();//
StringBuffer sb = null;
BufferedWriter bw = null;
Iterator<Student> it = list.iterator();// 创建list的迭代器
try {
bw = new BufferedWriter(new FileWriter("e:\\Per_Subject_ScodeFile.txt", true));
while (it.hasNext()) {
Student student = (Student) it.next();
if (student.scode.containsKey(subjectName)) {// 按指定科目进行判断,然后把满足要求的学生姓名和对应的分数加入map中
map.put(student.name, student.scode.get(subjectName));// 把学生名字添加到map中
}
}
List<Map.Entry<String, Double>> list1 = new ArrayList<Map.Entry<String, Double>>(map.entrySet());// 把map转化为List
Collections.sort(list1, new MyComparator());// 利用自定义比较器进行排序
bw.write(subjectName);// 把学科名写入文件
bw.newLine();// 换行
for (Entry<String, Double> entry : list1) {
System.out.println("名字:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
sb = new StringBuffer();
sb.append("名字:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
bw.write(sb.toString());
bw.newLine();
bw.flush();// 刷新缓冲区
}
} finally {
if (bw != null) {
bw.close();
}
}
}
/*
*
*
* 生成班级最高分和最低分的同学的成绩单文件
*
*
*/
private static void High_Lower_Scode_File(List<Student> list, List<Entry<String, Double>> list1)
throws IOException {
// 获得最高分数人的姓名
String name = list1.get(0).getKey();
System.out.println(name);
// 获得最低分数人的姓名
String name1 = list1.get(list.size() - 1).getKey();
System.out.println(name1);
StringBuffer sb = null;
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter("e:\\High_Lower_Scode_File.txt"));
for (Student stu : list) {// 遍历存储学生对象的容器
// 获得最高分的成绩单
if (stu.name.equals(name)) {// 根据学生姓名找到学生对象存储学科和成绩的map
bw.write(name);// 把学生姓名写入文件
bw.newLine();// 换行
Set<Map.Entry<String, Double>> set = stu.scode.entrySet();// 返回对应map集合Entry节点
Iterator<Map.Entry<String, Double>> it = set.iterator();// 创建迭代器
while (it.hasNext()) {
sb = new StringBuffer();
Map.Entry<String, Double> entry = (Map.Entry<String, Double>) it.next();// 遍历每一个Entry节点
System.out.println("名字:" + name + "学科:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
sb.append("学科:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
bw.write(sb.toString());
bw.newLine();
}
// 获得最低分的成绩单
} else if (stu.name.equals(name1)) {
bw.write(name1);
bw.newLine();
Set<Map.Entry<String, Double>> set = stu.scode.entrySet();
Iterator<Map.Entry<String, Double>> it = set.iterator();
while (it.hasNext()) {
sb = new StringBuffer();
Map.Entry<String, Double> entry = (Map.Entry<String, Double>) it.next();
System.out.println("名字:" + name1 + "学科:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
sb.append("学科:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
bw.write(sb.toString());
bw.newLine();
}
}
bw.flush();
}
} finally {
if (bw != null) {
bw.close();
}
}
}
/*
*
* 按TreeMap的值进行总分排序
*
*
*/
private static List<Map.Entry<String, Double>> ArrangTotalScode(Map<String, Double> map3) throws IOException {
List<Map.Entry<String, Double>> list = new ArrayList<Map.Entry<String, Double>>(map3.entrySet());// 把map转化为List
Collections.sort(list, new MyComparator());// 利用自定义比较器进行排序
StringBuffer sb = null;
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter("e:\\ArrangTotalScode.txt", true));
for (Entry<String, Double> entry : list) {// 遍历排序完成的list
sb = new StringBuffer();
System.out.println("姓名:" + entry.getKey() + "分数:" + map3.get(entry.getKey()));
sb.append("姓名:" + entry.getKey() + "\t" + "分数:" + map3.get(entry.getKey()));
bw.write(sb.toString());
bw.newLine();// 换行
bw.flush();// 刷新缓冲区
}
} finally {
if (bw != null) {
bw.close();
}
}
return list;// 返回有序的list
}
/*
*
* // 总分 // 个人成绩单
*
* *
*/
private static void totalScode(List<Student> list, Map<String, Map<String, Double>> map2, Map<String, Double> map3)
throws IOException {
Iterator<Student> it = list.iterator();// 创建学生对象容器list的容器
BufferedWriter bw = null;
StringBuffer sb = null;
while (it.hasNext()) {// 外层循环遍历人数
// System.out.println();
Student student2 = (Student) it.next();
System.out.println("id:" + student2.getId());
System.out.println("name" + student2.getName());
map2.put(student2.name, student2.scode);// 往map2中加入人名学科分数的映射
}
System.out.println(map2.size() + "map2");
Set<String> setMap = map2.keySet();// map2的Key代表人名
Iterator<String> it2 = setMap.iterator();// 创建map2的迭代器(map2中存放的是学生姓名和橙装学生科目成绩的映射)
Double sum = 0.0;
while (it2.hasNext()) {
bw = new BufferedWriter(new FileWriter("e:\\PersonScodeMenu.txt", true));
String student = (String) it2.next();// 遍历人(map2的key值部分,也就是人名)
System.out.println(student);// 打印的是人名(测试语句)
Set<Map.Entry<String, Double>> setMap2 = map2.get(student).entrySet();// 第二个小Map
Iterator<Map.Entry<String, Double>> it3 = setMap2.iterator();// 迭代学科和成绩
bw.write(student);// 把人名写入文件中
while (it3.hasNext()) {
Map.Entry<String, Double> entry = (Map.Entry<String, Double>) it3.next();
sum = sum + entry.getValue();
System.out.println("科目:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
sb = new StringBuffer();
sb.append("\r\n" + "科目:" + entry.getKey() + "\t" + "分数:" + entry.getValue());
bw.write(sb.toString());
bw.newLine();
}
System.out.println(sum);
map3.put(student, sum);// 把分数和人名的映射添加到Map3中
bw.write(student + "总分:" + String.valueOf(sum) + "\r\n");
bw.flush();
sum = 0.0;
}
}
/*
*
*
* 把学生信息加载到List中
*
*
*/
private static void PushScodeToList(List<Student> list) throws IOException {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("e:\\StudeentExamInfo.txt"));// 读取文件
String left = "";//临时存储学生学号的字符串变量
String str = null;// 临时存储按行读取的数据
Student student = null;
Map<String, Double> scode;
while ((str = br.readLine()) != null) {
scode = new HashMap<String, Double>();// 用于存储学科和其对应成绩的容器
// 把读取的信息用split()方法进行分割,得到一个长度为4的字符串数组
String[] str1 = str.split(",");
if (str1.length <= 1) {// 避免行之间的空格导致空指针异常(空行读取的数组长度为1)
continue;
}
//当学号不相等时,我们创建一个学生对象,然后把对应的成绩信息添加到该对象的Map容器中
if (!str1[0].equals(left)) {
scode.put(str1[2], Double.parseDouble(str1[3]));
student = new Student(Integer.parseInt(str1[0]), str1[1], scode);
list.add(student);
left = str1[0];
} else {
student.scode.put(str1[2], Double.parseDouble(str1[3]));
}
System.out.println(scode.size());
}
} finally {
if (br != null) {
br.close();
}
}
}
}