`
天使的左手
  • 浏览: 55823 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

xml学习鉴定

    博客分类:
  • java
xml 
阅读更多
实现招生录取系统中的部分功能(使用main方法作为程序入口)
1.	读XML文件,进过程序处理后,总成绩按降序排序,结果通过IO流输出到result_1.txt文件中。如:

班级[className classID]
学员姓名 学员ID[总分:457,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
学员姓名 学员ID[总分:453,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
班级[className classID]
学员姓名 学员ID[总分:457,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
学员姓名 学员ID[总分:454,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
学员姓名 学员ID[总分:445,学科ID:87,学科ID:83,学科ID:82,学科ID:83]

说明:
className classID用空格隔开,className为班级名称,classID为班级编号。
学员姓名 学员ID用空格隔开,每位学员成绩独占一行。总分为学员各学科成绩之和。


2.	通过IO读result_1.txt文件,以多线程方式实现大学录取学生功能
大学列表:清华大学、北京大学、南京大学、复旦大学、南京职业技术学院
说明:
A类大学为清华大学、北京大学,分数线为340,名额各为3名,;
B类大学为南京大学、复旦大学,分数线为320,名额各为10名;;
C类大学为南京职业技术学院,分数线为250,名额不限;
分数超过名额应该取最高分;达不到分数线可以不录取;
录取按大学类别进行:先A类,再B类,最后C类;
同类大学之间可以抢学生,同一学生只能被一所大学录取,以先录取为准;
结果通过IO输出result_2.txt,如:

清华大学:
学员姓名 学员ID[总分:457,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
北京大学:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
南京大学:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
复旦大学:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
南京职业技术学院:学员姓名 学员ID[总分:448,学科ID:87,学科ID:83,学科ID:82,学科ID:83]
未被录取学员:
学员姓名 学员ID[总分:128],学员姓名 学员ID[总分:215]


xml文档如下:
<root>
<!--表结构-->
<tables>
  <!--学员表-->
<table id="1000" name="studentTbl">
      <fields>
        <field id="studentId" /><!--学号-->
        <field id="name" /><!--姓名-->
        <field id="sex "/><!--性别-->
      </fields>
</table>

  <!--班级表-->
<table id="1001" name="classTbl">
      <fields>
        <field id="classId" /><!--班级编号-->
        <field id="name" /><!--班级名称-->
      </fields>
</table>

  <!--班级学员表-->
<table id="1004" name="classStudentTbl">
      <fields>
        <field id="classId" /><!--班级编号-->
        <field id="studentId" /><!--学号-->
      </fields>
</table>	

  <!--学科表-->
<table id="1002" name="subjectTbl">
      <fields>
        <field id="subjectId" /><!--学科编号-->
        <field id="name" /><!--学科名称-->
      </fields>
</table>

  <!--成绩表-->
<table id="1003" name="scoreTbl">
      <fields>
        <field id="studentId" /><!--学号-->
        <field id="subjectId" /><!--学科编号-->
        <field id="score" /><!--成绩-->
      </fields>
</table>	

</tables>

<!--数据信息,字段值以','分隔-->
<datas>

  <!--学员数据-->
<data tableid="1000">
<fields-data>st001,张一,男</fields-data>
<fields-data>st002,李二,男</fields-data>
<fields-data>st003,王三,女</fields-data>
<fields-data>st004,杨四,男</fields-data>
<fields-data>st005,赵五,男</fields-data>
<fields-data>st006,郑陆,女</fields-data>
<fields-data>st007,林世,男</fields-data>
<fields-data>st008,胡长,男</fields-data>
<fields-data>st009,邹家,男</fields-data>
<fields-data>st010,李方,男</fields-data>
<fields-data>st011,宁可,男</fields-data>
<fields-data>st012,张杂,男</fields-data>
<fields-data>st013,李度,男</fields-data>
<fields-data>st014,王等,女</fields-data>
<fields-data>st015,杨角,男</fields-data>
<fields-data>st016,赵度,男</fields-data>
<fields-data>st017,郑来,男</fields-data>
<fields-data>st018,林衡,男</fields-data>
<fields-data>st019,胡量,男</fields-data>
<fields-data>st020,邹代,女</fields-data>
<fields-data>st021,李码,男</fields-data>
<fields-data>st022,宁的,男</fields-data>
<fields-data>st023,张质,男</fields-data>
</data>

  <!--班级数据-->
<data tableid="1001">
<fields-data>1,一年级</fields-data>
<fields-data>2,二年级</fields-data>
<fields-data>3,三年级</fields-data>
</data>

  <!--学员班级信息-->
<data tableid="1004">
<fields-data>1,st001</fields-data>
<fields-data>2,st002</fields-data>
<fields-data>3,st003</fields-data>
<fields-data>1,st004</fields-data>
<fields-data>2,st005</fields-data>
<fields-data>3,st006</fields-data>
<fields-data>1,st007</fields-data>
<fields-data>2,st008</fields-data>
<fields-data>3,st009</fields-data>
<fields-data>2,st010</fields-data>
<fields-data>3,st011</fields-data>
<fields-data>3,st012</fields-data>
<fields-data>1,st013</fields-data>
<fields-data>1,st014</fields-data>
<fields-data>2,st015</fields-data>
<fields-data>3,st016</fields-data>
<fields-data>3,st017</fields-data>
<fields-data>2,st018</fields-data>
<fields-data>1,st019</fields-data>
<fields-data>1,st020</fields-data>
<fields-data>2,st021</fields-data>
<fields-data>3,st022</fields-data>
<fields-data>2,st023</fields-data>
<fields-data>3,st024</fields-data>
</data>

<!--学科数据-->
<data tableid="1002">
<fields-data>1,英语</fields-data>
<fields-data>2,化学</fields-data>
<fields-data>3,代数</fields-data>
<fields-data>4,计算机</fields-data>
</data>
<!--成绩数据-->
<data tableid="1003">
<fields-data>st001,1,80</fields-data>
<fields-data>st001,2,90</fields-data>
<fields-data>st001,3,70</fields-data>
<fields-data>st001,4,100</fields-data>
<fields-data>st002,1,77</fields-data>
<fields-data>st002,2,88</fields-data>
<fields-data>st002,3,99</fields-data>
<fields-data>st002,4,56</fields-data>
<fields-data>st003,1,96</fields-data>
<fields-data>st003,2,56</fields-data>
<fields-data>st003,3,88</fields-data>
<fields-data>st003,4,69</fields-data>
<fields-data>st004,1,78</fields-data>
<fields-data>st004,2,85</fields-data>
<fields-data>st004,3,83</fields-data>
<fields-data>st004,4,96</fields-data>
<fields-data>st005,1,79</fields-data>
<fields-data>st005,2,87</fields-data>
<fields-data>st005,3,91</fields-data>
<fields-data>st005,4,85</fields-data>
<fields-data>st006,1,79</fields-data>
<fields-data>st006,2,87</fields-data>
<fields-data>st006,3,68</fields-data>
<fields-data>st006,4,86</fields-data>
<fields-data>st007,1,55</fields-data>
<fields-data>st007,2,78</fields-data>
<fields-data>st007,3,90</fields-data>
<fields-data>st007,4,68</fields-data>
<fields-data>st008,1,69</fields-data>
<fields-data>st008,2,86</fields-data>
<fields-data>st008,3,75</fields-data>
<fields-data>st008,4,69</fields-data>
<fields-data>st009,1,84</fields-data>
<fields-data>st009,2,69</fields-data>
<fields-data>st009,3,90</fields-data>
<fields-data>st009,4,49</fields-data>
<fields-data>st010,1,77</fields-data>
<fields-data>st010,2,86</fields-data>
<fields-data>st010,3,99</fields-data>
<fields-data>st010,4,82</fields-data>
<fields-data>st011,1,67</fields-data>
<fields-data>st011,2,87</fields-data>
<fields-data>st011,3,69</fields-data>
<fields-data>st011,4,56</fields-data>
<fields-data>st012,1,44</fields-data>
<fields-data>st012,2,66</fields-data>
<fields-data>st012,3,99</fields-data>
<fields-data>st012,4,89</fields-data>
<fields-data>st013,1,67</fields-data>
<fields-data>st013,2,87</fields-data>
<fields-data>st013,3,78</fields-data>
<fields-data>st013,4,78</fields-data>
<fields-data>st014,1,56</fields-data>
<fields-data>st014,2,78</fields-data>
<fields-data>st014,3,88</fields-data>
<fields-data>st014,4,11</fields-data>
<fields-data>st015,1,0</fields-data>
<fields-data>st015,2,44</fields-data>
<fields-data>st015,3,66</fields-data>
<fields-data>st015,4,99</fields-data>
<fields-data>st016,1,67</fields-data>
<fields-data>st016,2,98</fields-data>
<fields-data>st016,3,78</fields-data>
<fields-data>st016,4,99</fields-data>
<fields-data>st017,1,89</fields-data>
<fields-data>st017,2,88</fields-data>
<fields-data>st017,3,90</fields-data>
<fields-data>st017,4,96</fields-data>
<fields-data>st018,1,93</fields-data>
<fields-data>st018,2,95</fields-data>
<fields-data>st018,3,96</fields-data>
<fields-data>st018,4,91</fields-data>
<fields-data>st019,1,98</fields-data>
<fields-data>st019,2,94</fields-data>
<fields-data>st019,3,93</fields-data>
<fields-data>st019,4,89</fields-data>	
<fields-data>st020,1,87</fields-data>
<fields-data>st020,2,96</fields-data>
<fields-data>st020,3,79</fields-data>
<fields-data>st020,4,82</fields-data>
<fields-data>st021,1,77</fields-data>
<fields-data>st021,2,87</fields-data>
<fields-data>st021,3,89</fields-data>
<fields-data>st021,4,86</fields-data>
<fields-data>st022,1,94</fields-data>
<fields-data>st022,2,76</fields-data>
<fields-data>st022,3,69</fields-data>
<fields-data>st022,4,79</fields-data>
<fields-data>st023,1,87</fields-data>
<fields-data>st023,2,57</fields-data>
<fields-data>st023,3,48</fields-data>
<fields-data>st023,4,48</fields-data>
<fields-data>st024,1,56</fields-data>
<fields-data>st024,2,68</fields-data>
<fields-data>st024,3,78</fields-data>
<fields-data>st024,4,81</fields-data>
<fields-data>st025,1,99</fields-data>
<fields-data>st025,2,47</fields-data>
<fields-data>st025,3,68</fields-data>
<fields-data>st025,4,98</fields-data>
<fields-data>st026,1,69</fields-data>
<fields-data>st026,2,95</fields-data>
<fields-data>st026,3,75</fields-data>
<fields-data>st026,4,95</fields-data>
<fields-data>st027,1,84</fields-data>
<fields-data>st027,2,85</fields-data>
<fields-data>st027,3,96</fields-data>
<fields-data>st027,4,76</fields-data>
<fields-data>st028,1,83</fields-data>
<fields-data>st028,2,95</fields-data>	
</data>

</datas>
</root>



实现:
import java.util.Set;
import java.util.TreeSet;

/**
 * 班级类
 */

public class Class implements Comparable<Class>
{
    private int classId;
    private String name;
    //维护本班级下面所有的student
    private Set<Student> students;

    public Class()
    {
        //有序存储student对象
        students = new TreeSet<Student>();
    }

    public Class(int classId, String name)
    {
        this();
        this.classId = classId;
        this.name = name;
    }

    public void setStudents(Set<Student> students)
    {
        this.students = students;
    }

    public Set<Student> getStudents()
    {
        return students;
    }

    public int getClassId()
    {
        return classId;
    }

    public void setClassId(int classId)
    {
        this.classId = classId;
    }

    public String getName()
    {
        return name;
    }

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

    @Override
    public String toString()
    {
        return "班级[" + name + " " + classId + "]";
    }

    @Override
    public int compareTo(Class o)
    {
        return classId - o.classId;
    }
}


import java.util.Set;
import java.util.TreeSet;

/**
 * 学生类
 */

public class Student implements Comparable<Student>
{
    private String studentId;
    private String name;
    private String sex;
    private Set<Score> scores;

    public Student()
    {
        scores = new TreeSet<Score>();
    }

    public Student(String studentId, String name, String sex)
    {
        this();
        this.studentId = studentId;
        this.name = name;
        this.sex = sex;
    }

    public Set<Score> getScores()
    {
        return scores;
    }

    public void setScores(Set<Score> scores)
    {
        this.scores = scores;
    }

    public String getStudentId()
    {
        return studentId;
    }

    public void setStudentId(String studentId)
    {
        this.studentId = studentId;
    }

    public String getName()
    {
        return name;
    }

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

    public String getSex()
    {
        return sex;
    }

    public void setSex(String sex)
    {
        this.sex = sex;
    }

    //按总成绩对学生排序,如果总成绩相同,按学号排序
    @Override
    public int compareTo(Student o)
    {
        float total = 0f;
        for (Score score : scores)
            total += score.getScore();

        float o_total = 0f;
        for (Score score : o.getScores())
            o_total += score.getScore();
        int result = (int) (o_total - total);
        if (result != 0)
            return result;
        return studentId.compareTo(o.studentId);
    }

    @Override
    public String toString()
    {
        StringBuilder result = new StringBuilder();
        result.append(name).append(' ').append(studentId).append("[总分:%3d, ");
        float total = 0f;
        for (Score score : scores)
        {
            result.append(score.getCourse().getName()).append(":").append(String.format("%3d", (int) score.getScore()))
                    .append(", ");
            total += score.getScore();
        }
        return String.format(result.substring(0, result.length() - 2) + "]", (int) total);
    }
}


/**
 * 成绩类
 */

public class Score implements Comparable<Score>
{
    private float score;
    private Student student;
    private Course course;

    public Score(float score, Student student, Course course)
    {
        this.score = score;
        this.student = student;
        this.course = course;
    }

    public Score()
    {
    }

    public float getScore()
    {
        return score;
    }

    public void setScore(float score)
    {
        this.score = score;
    }

    public Student getStudent()
    {
        return student;
    }

    public void setStudent(Student student)
    {
        this.student = student;
    }

    public Course getCourse()
    {
        return course;
    }

    public void setCourse(Course course)
    {
        this.course = course;
    }

    //按课程号进行排序
    @Override
    public int compareTo(Score o)
    {
        return course.getSujectId() - o.course.getSujectId();
    }
}


/**
 * 课程类
 */

public class Course
{
    private int sujectId;
    private String name;

    public Course()
    {
    }

    public Course(int sujectId, String name)
    {
        this.sujectId = sujectId;
        this.name = name;
    }

    public int getSujectId()
    {
        return sujectId;
    }

    public void setSujectId(int sujectId)
    {
        this.sujectId = sujectId;
    }

    public String getName()
    {
        return name;
    }

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

}


import java.io.IOException;
import java.util.HashMap;
import java.util.Set;
import java.util.TreeSet;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 
 *  解析xml文档的工具类 
 */

public class DataParser
{
    //定义解析数据过程中需要用到的一些常量数据
    private static final String DATA_ELEMENT = "data";
    private static final String FIELD_DATA_ELEMENT = "fields-data";
    private static final String TABLE_ID_ATTRIBUTE = "tableid";
    private static final String STUDENT_DATA = "1000";
    private static final String CLASS_DATA = "1001";
    private static final String COURSE_DATA = "1002";
    private static final String SCORE_DATA = "1003";
    private static final String STUDENT_CLASS_DATA = "1004";

    public static void main(String[] args)
    {
        Set<Class> classes = getClasses("src/data.xml");
        PrintWriter writer = new PrintWriter(new OutputStreamWriter(new FileOutputStream("result_1.txt"), "UTF-8"), true);
        for (Class cls : classes)
        {
            writer.println(cls);
            for (Student student : cls.getStudents())
            {
                writer.println(student);
            }
        }
        writer.close();
    }

    public static Set<Class> getClasses(String filePath)
    {
        DocumentBuilderFactory parserFactory = DocumentBuilderFactory.newInstance();
        //解析完成的数据 暂时存储在map集合中 方便查找
        HashMap<Integer, Class> cls_map = new HashMap<Integer, Class>();
        HashMap<String, Student> stu_map = new HashMap<String, Student>();
        HashMap<Integer, Course> cour_map = new HashMap<Integer, Course>();

        try
        {
            DocumentBuilder parser = parserFactory.newDocumentBuilder();
            Document doc = parser.parse(filePath);
            XPath xpath = XPathFactory.newInstance().newXPath();
            //xpath表达式 %s表示待替换的属性值
            String expr = "//" + DATA_ELEMENT + "[@" + TABLE_ID_ATTRIBUTE + "=%s]";
            
            //解析class数据
            Element cls_elt = (Element) xpath.compile(String.format(expr, CLASS_DATA)).evaluate(doc, XPathConstants.NODE);
            NodeList cls_items = cls_elt.getElementsByTagName(FIELD_DATA_ELEMENT);
            for (int i = 0; i < cls_items.getLength(); i++)
            {
                String item = cls_items.item(i).getTextContent();
                String[] parts = item.split(",");
                if (parts.length != 2)
                    throw new IllegalArgumentException("invalid class data item: " + item);

                int classId = Integer.parseInt(parts[0].trim());
                String name = parts[1].trim();
                cls_map.put(classId, new Class(classId, name));
            }

            //解析student数据
            Element stu_elt = (Element) xpath.compile(String.format(expr, STUDENT_DATA)).evaluate(doc, XPathConstants.NODE);
            NodeList stu_items = stu_elt.getElementsByTagName(FIELD_DATA_ELEMENT);
            for (int i = 0; i < stu_items.getLength(); i++)
            {
                String item = stu_items.item(i).getTextContent();
                String[] parts = item.split(",");
                if (parts.length != 3)
                    throw new IllegalArgumentException("invalid student data item: " + item);

                String studentId = parts[0].trim();
                String name = parts[1].trim();
                String sex = parts[2].trim();
                stu_map.put(studentId, new Student(studentId, name, sex));
            }

            //解析course数据
            Element cour_elt = (Element) xpath.compile(String.format(expr, COURSE_DATA)).evaluate(doc, XPathConstants.NODE);
            NodeList cour_items = cour_elt.getElementsByTagName(FIELD_DATA_ELEMENT);
            for (int i = 0; i < cour_items.getLength(); i++)
            {
                String item = cour_items.item(i).getTextContent();
                String[] parts = item.split(",");
                if (parts.length != 2)
                    throw new IllegalArgumentException("invalid course data item: " + item);

                int courseId = Integer.parseInt(parts[0].trim());
                String name = parts[1].trim();
                cour_map.put(courseId, new Course(courseId, name));
            }

            //解析score数据
            Element score_elt = (Element) xpath.compile(String.format(expr, SCORE_DATA)).evaluate(doc, XPathConstants.NODE);
            NodeList score_items = score_elt.getElementsByTagName(FIELD_DATA_ELEMENT);
            Score score;
            for (int i = 0; i < score_items.getLength(); i++)
            {
                String item = score_items.item(i).getTextContent();
                String[] parts = item.split(",");
                if (parts.length != 3)
                    throw new IllegalArgumentException("invalid score data item: " + item);

                String studentId = parts[0].trim();
                Student stu = stu_map.get(studentId);
                if (stu == null)
                {
                    System.out.println("invalid student id: " + studentId);
                    continue;
                }

                int courseId = Integer.parseInt(parts[1].trim());
                Course cour = cour_map.get(courseId);
                if (cour == null)
                {
                    System.out.println("invalid course id: " + courseId);
                    continue;
                }

                float grade = Float.parseFloat(parts[2].trim());
                score = new Score();
                score.setScore(grade);
                score.setCourse(cour);
                score.setStudent(stu);

                stu.getScores().add(score);
            }

            //解析class-student数据
            Element stu_cls_elt = (Element) xpath.compile(String.format(expr, STUDENT_CLASS_DATA)).evaluate(doc,
                    XPathConstants.NODE);
            NodeList stu_cls_items = stu_cls_elt.getElementsByTagName(FIELD_DATA_ELEMENT);
            for (int i = 0; i < stu_cls_items.getLength(); i++)
            {
                String item = stu_cls_items.item(i).getTextContent();
                String[] parts = item.split(",");
                if (parts.length != 2)
                    throw new IllegalArgumentException("invalid class to student mapping data item: " + item);

                int classId = Integer.parseInt(parts[0].trim());
                String studentId = parts[1].trim();
                Class cls = cls_map.get(classId);
                if (cls == null)
                {
                    System.out.println("invalid class id: " + classId);
                    continue;
                }

                Student stu = stu_map.get(studentId);
                if (stu == null)
                {
                    System.out.println("invalid student id: " + studentId);
                    continue;
                }
                cls.getStudents().add(stu);
            }
        }
        catch (ParserConfigurationException e)
        {
            throw new RuntimeException("parser configuration error", e);
        }
        catch (SAXException e)
        {
            throw new RuntimeException("parse error", e);
        }
        catch (IOException e)
        {
            throw new RuntimeException("io operation error", e);
        }
        catch (XPathExpressionException e)
        {
            throw new RuntimeException("xpath expression error", e);
        }
        
        //最终将class数据存储到treemap集合返回
        return new TreeSet<Class>(cls_map.values());
    }
}


-------------------执行结果 result_1.txt-------------------------
班级[一年级 1]
胡量 st019[总分:374, 英语: 98, 化学: 94, 代数: 93, 计算机: 89]
邹代 st020[总分:344, 英语: 87, 化学: 96, 代数: 79, 计算机: 82]
杨四 st004[总分:342, 英语: 78, 化学: 85, 代数: 83, 计算机: 96]
张一 st001[总分:340, 英语: 80, 化学: 90, 代数: 70, 计算机:100]
李度 st013[总分:310, 英语: 67, 化学: 87, 代数: 78, 计算机: 78]
林世 st007[总分:291, 英语: 55, 化学: 78, 代数: 90, 计算机: 68]
王等 st014[总分:233, 英语: 56, 化学: 78, 代数: 88, 计算机: 11]
班级[二年级 2]
林衡 st018[总分:375, 英语: 93, 化学: 95, 代数: 96, 计算机: 91]
李方 st010[总分:344, 英语: 77, 化学: 86, 代数: 99, 计算机: 82]
赵五 st005[总分:342, 英语: 79, 化学: 87, 代数: 91, 计算机: 85]
李码 st021[总分:339, 英语: 77, 化学: 87, 代数: 89, 计算机: 86]
李二 st002[总分:320, 英语: 77, 化学: 88, 代数: 99, 计算机: 56]
胡长 st008[总分:299, 英语: 69, 化学: 86, 代数: 75, 计算机: 69]
张质 st023[总分:240, 英语: 87, 化学: 57, 代数: 48, 计算机: 48]
杨角 st015[总分:209, 英语:  0, 化学: 44, 代数: 66, 计算机: 99]
班级[三年级 3]
郑来 st017[总分:363, 英语: 89, 化学: 88, 代数: 90, 计算机: 96]
赵度 st016[总分:342, 英语: 67, 化学: 98, 代数: 78, 计算机: 99]
郑陆 st006[总分:320, 英语: 79, 化学: 87, 代数: 68, 计算机: 86]
宁的 st022[总分:318, 英语: 94, 化学: 76, 代数: 69, 计算机: 79]
王三 st003[总分:309, 英语: 96, 化学: 56, 代数: 88, 计算机: 69]
张杂 st012[总分:298, 英语: 44, 化学: 66, 代数: 99, 计算机: 89]
邹家 st009[总分:292, 英语: 84, 化学: 69, 代数: 90, 计算机: 49]
宁可 st011[总分:279, 英语: 67, 化学: 87, 代数: 69, 计算机: 56]



public class SelectStudent
{
    //构建一个简单的Student类,存储从txt文件解析出来的Student对象
    static class SimpleStudent implements Comparable<SimpleStudent>
    {
        //总成绩
        private int score;
        //考生详细信息
        private String info;

        public SimpleStudent()
        {
        }

        public SimpleStudent(int score, String info)
        {
            this.score = score;
            this.info = info;
        }

        public int getScore()
        {
            return score;
        }

        public void setScore(int score)
        {
            this.score = score;
        }

        public String getInfo()
        {
            return info;
        }

        public void setInfo(String info)
        {
            this.info = info;
        }

        //按总成绩排序,如果总成绩相同,按详细信息排序
        @Override
        public int compareTo(SimpleStudent o)
        {
            int result = o.score - score;
            if (result != 0)
                return result;
            return info.compareTo(o.info);
        }

        @Override
        public String toString()
        {
            return info;
        }
    }

    private final Lock lock = new ReentrantLock();
    //A类线程等待的信号
    private final Condition con_a = lock.newCondition();
    //B类线程等待的信号
    private final Condition con_b = lock.newCondition();
    //C类线程等待的信号    
    private final Condition con_c = lock.newCondition();
    //使用一个线程池运行相关的Task
    private ExecutorService executor = Executors.newCachedThreadPool();
    private int state = 0;

    public SelectStudent()
    {
    }

    public void shutdownExecutorNow()
    {
        if (!executor.isShutdown())
            executor.shutdownNow();
    }

    //线程管理类
    abstract class Monitor implements Runnable
    {
        CountDownLatch cdl_before;
        CountDownLatch cdl_after;

        Monitor(CountDownLatch cdl_before, CountDownLatch cdl_after)
        {
            this.cdl_before = cdl_before;
            this.cdl_after = cdl_after;
        }

        @Override
        public void run()
        {
            //获得锁
            lock.lock();
            try
            {
                //具体实现由子类完成
                process();
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException("interrupted error", e);
            }
            finally
            {
                //释放锁
                lock.unlock();
            }
        }

        abstract void process() throws InterruptedException;
    }

    //A类管理线程
    class MonitorA extends Monitor
    {
        MonitorA(CountDownLatch cdl_before, CountDownLatch cdl_after)
        {
            super(cdl_before, cdl_after);
        }

        @Override
        void process() throws InterruptedException
        {
            //当state=0 表明当前状态允许执行
            while (state % 3 != 0)
                //若条件不符合,在con_a条件上等待
                con_a.await();

            //通知A类线程开始执行
            cdl_before.countDown();
            //等待所有A类线程执行完成
            cdl_after.await();
            state++;
            //通知B类管理线程开始执行
            con_b.signal();
        }
    }

    //B类管理线程
    class MonitorB extends Monitor
    {
        MonitorB(CountDownLatch cdl_before, CountDownLatch cdl_after)
        {
            super(cdl_before, cdl_after);
        }

        @Override
        void process() throws InterruptedException
        {
            //state=1 允许执行
            while (state % 3 != 1)
                //若条件不符合,在con_b条件上等待
                con_b.await();

            //通知B类线程开始执行
            cdl_before.countDown();
            //等待所有B类线程执行完成
            cdl_after.await();
            state++;
            //通知C类管理线程开始执行
            con_c.signal();
        }
    }

    //C类管理线程
    class MonitorC extends Monitor
    {
        MonitorC(CountDownLatch cdl_before, CountDownLatch cdl_after)
        {
            super(cdl_before, cdl_after);
        }

        @Override
        void process() throws InterruptedException
        {
            //state=2 运行执行
            while (state % 3 != 2)
                //若条件不符合,在con_c条件上等待
                con_c.await();

            //通知所有C类线程执行
            cdl_before.countDown();
        }
    }

    //模拟TimeUnit.unit.sleep 非阻塞方法
    void sleep(TimeUnit unit, long duration)
    {
        long startTime = System.nanoTime();
        while (System.nanoTime() - startTime < unit.toNanos(duration))
        {
        }
    }

    //录取考生线程(A类,B类,C类)
    class SelectTask implements Runnable
    {
        //学校名称
        private String name;
        //录取人数
        private int num;
        //分数线
        private int grade;
        //考生列表
        private List<SimpleStudent> students;
        //消息队列
        private ConcurrentLinkedQueue<String> queue;
        //任务开始条件
        private CountDownLatch cdl_before;
        //任务结束条件
        private CountDownLatch cdl_after;

        SelectTask(String schoolName, List<SimpleStudent> stus, ConcurrentLinkedQueue<String> queue, int selectNum, int grade,
                CountDownLatch cdl_before, CountDownLatch cdl_after)
        {
            name = schoolName;
            students = stus;
            num = selectNum;
            this.grade = grade;
            this.queue = queue;
            this.cdl_before = cdl_before;
            this.cdl_after = cdl_after;
        }

        @Override
        public void run()
        {
            try
            {
                //等待任务开始条件
                cdl_before.await();
                SimpleStudent student;
                int i = 0;
                try
                {
                    //开始录取操作
                    for (i = 0; i < num; i++)
                    {
                        sleep(TimeUnit.MILLISECONDS, 5);
                        synchronized (students)
                        {
                            //如果学校列表已经为空,强制终止整个录取过程(强制关闭线程池)
                            if (students.isEmpty())
                            {
                                queue.offer(name + ": 没有可录取的学生!");
                                shutdownExecutorNow();
                                return;
                            }

                            student = students.get(0);
                            //如果没有达到分数线,终止录取过程
                            if (student.getScore() < grade)
                                break;
                            
                            //将录取信息加入到消息队列
                            queue.offer(name + ": " + students.remove(0).info);
                        }
                    }
                }
                finally
                {
                    //将统计消息加入消息队列
                    //放在finally中,即使强制终止当前线程,也会执行该语句
                    queue.offer(name + ":[" + ((num == i || num == Integer.MAX_VALUE) ? "达标" : "未达标") + "] 当前录取" + i + "/总名额"
                            + (num == Integer.MAX_VALUE ? "(无限制)" : num));
                }
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException("interrupted error", e);
            }
            finally
            {
                //当前任务运行结束
                cdl_after.countDown();
            }
        }
    }

    //打印未被录取考生信息的线程
    class NotSelectTask implements Runnable
    {
        //考生列表
        private List<SimpleStudent> students;
        //消息队列
        private ConcurrentLinkedQueue<String> queue;
        //任务开始条件
        private CountDownLatch cdl;

        public NotSelectTask(List<SimpleStudent> students, ConcurrentLinkedQueue<String> queue, CountDownLatch cdl)
        {
            this.students = students;
            this.queue = queue;
            this.cdl = cdl;
        }

        @Override
        public void run()
        {
            try
            {
                //等待任务开始条件(所有C类线程执行完毕)
                cdl.await();
                while (!students.isEmpty())
                    //将未被录取考生信息加入消息队列
                    queue.offer("未被录取:" + students.remove(0).info);

                //终止线程池
                executor.shutdown();
            }
            catch (InterruptedException e)
            {
                throw new RuntimeException("wait interrupted", e);
            }
        }
    }

    //消息处理线程 从消息队列取出消息,通过输出流写到文件中
    class OutputTask implements Runnable
    {
        private ConcurrentLinkedQueue<String> queue;
        private PrintWriter writer;

        OutputTask(ConcurrentLinkedQueue<String> queue, String outFile)
        {
            this.queue = queue;
            try
            {
                writer = new PrintWriter(new FileOutputStream(outFile));
            }
            catch (FileNotFoundException e)
            {
                throw new RuntimeException(e);
            }
        }

        @Override
        public void run()
        {
            String content = null;
            while (true)
            {
                //如果录取线程池已经终止且当前消息队列为空,退出
                if (executor.isTerminated() && queue.isEmpty())
                    break;
                content = queue.poll();
                if (content != null)
                    writer.println(content);
                writer.flush();
            }
            writer.close();
        }
    }

    public static void main(String[] args) throws Exception
    {
        SelectStudent ss = new SelectStudent();
        List<SimpleStudent> stus = ss.parseTextFile("result_1.txt");
        ss.select(stus);
    }

    public void select(List<SimpleStudent> list)
    {
        //消息队列
        ConcurrentLinkedQueue<String> queue = new ConcurrentLinkedQueue<String>();
        //构建消息处理线程
        new Thread(new OutputTask(queue, "result_2.txt")).start();

        CountDownLatch cdl_11 = new CountDownLatch(1);
        CountDownLatch cdl_21 = new CountDownLatch(2);
        //A类管理线程
        executor.execute(new MonitorA(cdl_11, cdl_21));
        //A类线程
        executor.execute(new SelectTask("清华大学", list, queue, 3, 340, cdl_11, cdl_21));
        //A类线程
        executor.execute(new SelectTask("北京大学", list, queue, 3, 340, cdl_11, cdl_21));

        CountDownLatch cdl_12 = new CountDownLatch(1);
        CountDownLatch cdl_22 = new CountDownLatch(2);
        //B类管理线程
        executor.execute(new MonitorB(cdl_12, cdl_22));
        //B类线程
        executor.execute(new SelectTask("南京大学", list, queue, 10, 320, cdl_12, cdl_22));
        //B类线程
        executor.execute(new SelectTask("复旦大学", list, queue, 10, 320, cdl_12, cdl_22));

        CountDownLatch cdl_13 = new CountDownLatch(1);
        CountDownLatch cdl_23 = new CountDownLatch(1);
        //C类管理线程
        executor.execute(new MonitorC(cdl_13, cdl_23));
        //C类线程
        executor.execute(new SelectTask("南京职业技术学院", list, queue, Integer.MAX_VALUE, 250, cdl_13, cdl_23));

        //处理未被录取考生线程
        executor.execute(new NotSelectTask(list, queue, cdl_23));
    }

    //从txt文档解析考生信息,并按总成绩进行排序
    public List<SimpleStudent> parseTextFile(String filename) throws Exception
    {
        BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(filename), "UTF-8"));
        String line = null;
        List<SimpleStudent> students = new ArrayList<SimpleStudent>();
        SimpleStudent stu;
        while (null != (line = reader.readLine()))
        {
            int index = line.indexOf("总分");
            if (index == -1)
                continue;

            String score_str = line.substring(index + 3, line.indexOf(",", index));
            stu = new SimpleStudent(Integer.parseInt(score_str), line);
            students.add(stu);
        }
        Collections.sort(students);
        return students;
    }
}


-------------------执行结果 result_2.txt-------------------------
北京大学: 林衡 st018[总分:375, 英语: 93, 化学: 95, 代数: 96, 计算机: 91]
北京大学: 胡量 st019[总分:374, 英语: 98, 化学: 94, 代数: 93, 计算机: 89]
清华大学: 郑来 st017[总分:363, 英语: 89, 化学: 88, 代数: 90, 计算机: 96]
北京大学: 李方 st010[总分:344, 英语: 77, 化学: 86, 代数: 99, 计算机: 82]
北京大学:[达标] 当前录取3/总名额3
清华大学: 邹代 st020[总分:344, 英语: 87, 化学: 96, 代数: 79, 计算机: 82]
清华大学: 杨四 st004[总分:342, 英语: 78, 化学: 85, 代数: 83, 计算机: 96]
清华大学:[达标] 当前录取3/总名额3
复旦大学: 赵五 st005[总分:342, 英语: 79, 化学: 87, 代数: 91, 计算机: 85]
复旦大学: 赵度 st016[总分:342, 英语: 67, 化学: 98, 代数: 78, 计算机: 99]
复旦大学: 张一 st001[总分:340, 英语: 80, 化学: 90, 代数: 70, 计算机:100]
复旦大学: 李码 st021[总分:339, 英语: 77, 化学: 87, 代数: 89, 计算机: 86]
南京大学: 李二 st002[总分:320, 英语: 77, 化学: 88, 代数: 99, 计算机: 56]
复旦大学: 郑陆 st006[总分:320, 英语: 79, 化学: 87, 代数: 68, 计算机: 86]
南京大学:[未达标] 当前录取1/总名额10
复旦大学:[未达标] 当前录取5/总名额10
南京职业技术学院: 宁的 st022[总分:318, 英语: 94, 化学: 76, 代数: 69, 计算机: 79]
南京职业技术学院: 李度 st013[总分:310, 英语: 67, 化学: 87, 代数: 78, 计算机: 78]
南京职业技术学院: 王三 st003[总分:309, 英语: 96, 化学: 56, 代数: 88, 计算机: 69]
南京职业技术学院: 胡长 st008[总分:299, 英语: 69, 化学: 86, 代数: 75, 计算机: 69]
南京职业技术学院: 张杂 st012[总分:298, 英语: 44, 化学: 66, 代数: 99, 计算机: 89]
南京职业技术学院: 邹家 st009[总分:292, 英语: 84, 化学: 69, 代数: 90, 计算机: 49]
南京职业技术学院: 林世 st007[总分:291, 英语: 55, 化学: 78, 代数: 90, 计算机: 68]
南京职业技术学院: 宁可 st011[总分:279, 英语: 67, 化学: 87, 代数: 69, 计算机: 56]
南京职业技术学院:[达标] 当前录取8/总名额(无限制)
未被录取:张质 st023[总分:240, 英语: 87, 化学: 57, 代数: 48, 计算机: 48]
未被录取:王等 st014[总分:233, 英语: 56, 化学: 78, 代数: 88, 计算机: 11]
未被录取:杨角 st015[总分:209, 英语:  0, 化学: 44, 代数: 66, 计算机: 99]
分享到:
评论

相关推荐

    华为2009年软件公司技能鉴定编程实战java版.rar

    【标题】华为2009年软件公司技能...通过学习这些文档和代码,Java开发者可以系统地复习和提升编程技能,尤其是针对华为的技能鉴定标准。同时,这些资料也可以作为日常学习和项目开发的参考资料,加深对Java编程的理解。

    实习鉴定表及实习报告(鉴定表有需要公司盖章)打印版.doc

    通过学习RSS,实习生可以了解到XML应用的基本原理和技术。 知识点五:XSLT和XPath的应用 XSLT(eXtensible Stylesheet Language Transformation)是一种用于转换XML文档结构的语言,而XPath是一种用于在XML文档中...

    java技能鉴定2

    通过"JAVA技能鉴定试题_第二套"和"JAVA技能鉴定试题_第二套答案"这两个文档,你可以对上述知识点进行深入学习和练习,以提高你的Java技能水平。这份鉴定不仅测试了理论知识,还评估了实际编程和问题解决能力,是成为...

    实习鉴定表及实习报告(鉴定表有需要公司盖章)打印版(2).doc

    实习鉴定表和实习报告是衡量实习生在实习期间学习、工作情况的重要文档,通常由实习单位和学校共同评估。福建农林大学计算机与信息学院的实习报告要求详细且规范,旨在提升学生的实践技能和专业知识。 一、实习报告...

    实习鉴定表及实习报告(鉴定表有需要公司盖章)打印版(1).doc

    而实习鉴定表与实习报告则是对实习过程进行系统评估和总结的工具,它们对于评估学生的实习表现,促进学生的学习和成长具有重要作用。 实习鉴定表的作用主要是评价实习生在实习期间的表现与成果,它涉及到学生的实习...

    [计算机专业大学生实习鉴定].docx

    ### 计算机专业大学生实习鉴定相关知识点 #### 一、计算机软件技能 - **办公软件**:Office XP,包括Word、Excel、PowerPoint等,是办公自动化的重要工具,掌握这些软件可以有效提升工作效率和质量。 - **图形设计...

    路过的小盼毕设-鞋类数据集

    "labels"文件夹包含每个图像对应的标注信息,这些信息通常以XML或CSV格式存储,列明了每个目标物体的边界框坐标以及对应的类别标签。"images"文件夹则包含实际的图像文件,这些图片可用于训练和验证深度学习模型。 ...

    软件开发技术人员职业标准.pdf

    + 进阶学习目标 4. 技能要求 * 专业知识要求: + Microsoft .NET 框架和 Microsoft Visual Studio .NET 集成开发环境的主要概念 + C# 语言的基本原理 + 对象的创建 + 面向对象的编程技术 + 使用 ADO...

    精品(2021-2022年)资料软件开发技术人员职业标准.doc

    - **ASP.NET应用程序开发**:涉及.NET Framework概述、Web窗体创建、代码添加、用户验证、数据访问、XML Web Service等。 - **SQL Server 2000数据库应用和管理**:包括数据库管理系统基础、数据模型、Transact-...

    重庆大学j2ee课件(PPT)

    【描述】提到的"从别处找的重庆大学的课件,大家给鉴定一下!"表明这是一个共享资源,可能来自互联网上的学习社区或个人分享。用户希望其他人能够验证这些课件的质量和准确性,以确保它们可以作为学习J2EE的有效资料...

    AJAX客户端说明,XMLHttpRequest对象

    下面我们来学习学习这个咚咚,希望能给更多的人带来帮助。 首先当然是要了解一下浏览器中的XMLHttp对象了: XMLHTTP方法: 备注:客户机可以使用XMLHTTP对象发送任意的HTTP请求,接受HTTP应答,还可以对应答的XML文档...

    教学辅助系统概要分析

    例如,使用连接池和JDBC进行数据库访问,使用XML文件存储系统配置信息,并通过DOM4J进行读取和修改。 ##### 4.2 物理结构设计 明确了每个数据结构中的数据项存储要求、访问方法以及存取单位等细节,以确保数据的...

    数据采集聚类分析及在GIS山东大学嵌入式系统实验室实用教案.pptx

    国内自主研发的监测设备由于缺乏标准化鉴定,难以进入市场,导致高端海洋仪器市场被国外产品主导。 海洋监测系统的主要功能包括实时采集海洋基本监测要素,如水温、盐度、pH值和硅酸盐等,通过无线GPRS网络实现实时...

    基于ssm+web的邮票鉴赏系统及实现.zip

    邮票鉴赏系统是一种在线平台,它允许用户浏览、学习和分享关于邮票的知识,同时提供鉴定服务。这个系统是基于SSM(Spring、SpringMVC、MyBatis)框架和Web技术构建的,旨在为集邮爱好者提供一个便捷、互动的交流环境...

    自演化智能软件系统平台的架构设计和技术研究.pdf

    自演化智能软件系统平台是一种革命性的软件开发平台,它与传统静态软件平台不同,能够根据不同的使用案例和场景,通过经验学习和演进来改变自身的架构。这种平台的设计理念和技术研究涉及以下几个关键知识点: 1. ...

    新常态下互联网+在档案管理中的运用.docx

    1. 构建"互联网+"档案管理新模式:档案管理应当超越传统的收集、保管和使用,通过XML、Web Services等技术实现不同系统间的集成,打破信息孤岛,增强档案信息的完整性,为决策提供数据支持。 2. 加强档案资源体系...

    初识 Spring Security - v1.1.pdf

    - **了解前置知识**:为了更好地学习Spring Security,读者需要具备一定的基础知识,包括但不限于AOP(面向切面编程)、Servlet等相关概念;如果熟悉Java语言则更易于理解Spring Security的相关概念和操作。 #### ...

    档案职称评审考试培训练习题--《档案工作实务》第四章--电子文件管理-----第五章档案信息化建设.docx

    - **知识点解析**:根据《档案管理软件功能要求暂行规定》,档案管理软件的数据交换格式应支持 DBF 格式和 XML 文档。这两种格式都广泛应用于数据交换领域,便于不同系统之间的数据共享和交互。 **16. 日志文件保存...

    RequestTool:一个独立的Java应用程序和库,可从ProteomicsDB的OData服务检索数据

    ProteomicsDB是一个全球性的蛋白质组学数据库,存储了大量的实验数据,包括蛋白质鉴定、定量、相互作用以及功能注释等。它提供OData服务,使得科研人员可以通过API直接访问这些数据,进行数据分析和研究。 ...

    批发鸡蛋的软件

    【批发鸡蛋的软件】是一款基于Visual Basic...通过学习和理解源代码,用户不仅可以自定义软件功能,还能增进对VB编程的理解,为未来的技术扩展打下基础。在使用过程中,商家应注意数据安全和备份,确保业务的稳定运行。

Global site tag (gtag.js) - Google Analytics