java - 如何在 Java 中比较和排序两个数组列表

标签 java

我从硬盘驱动器上的两个文件获取输入:

studentNames.txt 和 StudentScores.txt - 姓名包含学生 ID 和姓名,分数包含学生 ID 和分数。我已将数据放入两个 ArrayList 中,并希望对数据进行排序,以便成绩转到匹配的 ID。

例如:

+------+--------------+---------+
|  ID  |     Name     |  Grade  |
+------+--------------+---------+
| 3305 | Smith Henry  | 92.0    |
| 5555 | Eddy Olivia  | 95.5    |
| 8915 | Johnson Luke | 98.5    |
+------+--------------+---------+

数据继续仅填充 ID/成绩 - 我知道我需要使用 if 语句,但我该如何做呢?

这是我的代码:

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

public class P_Supplemental_9 {

public static void main(String[] args) throws FileNotFoundException {
   File file1 = new File("c:/temp/studentNames.txt");
   File file2 = new File("c:/temp/studentScores.txt");

   if(file1.exists()) {
   Scanner input = new Scanner(file1);

   ArrayList<Student> students = new ArrayList();

   while(input.hasNext()) {
   students.add(new Student(input.nextInt(),input.nextLine()));
   }

   input.close();

   for(int o = 0;o < students.size();o++) {
   System.out.printf("%10d %20s avg\n", students.get(o).getStuId(),     students.get(o).getStuName());

   } // end for

   }

   if(file2.exists()) {
       Scanner input = new Scanner(file2);

       ArrayList<Student> grades = new ArrayList();

       while(input.hasNext()) {
           grades.add(new Student(input.nextInt(), input.nextLine()));

       } /// end while
       input.close();

   for(int o = 0;o < grades.size();o++) {

       System.out.printf("%10d %20s avg\n", grades.get(o).getStuId(), grades.get(o).getStuName());
   } // end for

   } // end if(file2.exists)





  } // end main method
 } // end P_Supplemental_9



class Student {
    private int stuId;
    private String stuName;
    private ArrayList <Double> grades;

    Student(int idIn, String nameIn) {

        this.stuId = idIn;
        this.stuName = nameIn;
       } // end student class

    Student(int idIn, ArrayList gradesIn) {
        this.stuId = idIn;
        this.grades = gradesIn;

    }

        public int getStuId() {
            return stuId;
        }

        /**
         * @param stuId the stuId to set
         */
        public void setStuId(int stuId) {
            this.stuId = stuId;
        }

        /**
         * @return the stuName
         */
        public String getStuName() {
            return stuName;
        }

        /**
         * @param stuName the stuName to set
         */
        public void setStuName(String stuName) {
            this.stuName = stuName;
        }

        /**
         * @return the grades
         */
        public ArrayList getGrades() {
            return grades;
        }

        /**
         * @param grades the grades to set
         */
        public void setGrades(ArrayList grades) {
            this.grades = grades;
        }

} // end student class

这是来自 Studentnames.txt 的数据

3305 Smith Henry
5555 Eddy Olivia
8915 Johnson Luke

这是来自 Studentscores.txt 的数据

3305 92.0
5555 95.5
8915 98.5
3305 89.0
5555 90.5
8915 95.5
3305 78.5
5555 85.0
8915 82.0

最佳答案

您可以使用Collections#sort(List, Comparator)对两个列表进行排序。

假设学生与其分数之间是一对一的关系,这将允许您获取学生和分数以及列表的每个元素。

我想象它看起来像这样。

Collections.sort(studentNames, new Comparator<Student>() {
    public int compareTo(Student o1, Student o2) {
        return o1.getStuId() - o2.getStuId();
    }
});

这将为您提供按学生 ID 排序的学生列表

然后,您可以使用相同的概念对分数列表进行排序。完成后,这两个列表现在应该按学生 ID 顺序排列,并且您应该能够循环它们。

另一个想法是将学生和分数存储在与学生 ID 相关的Map 中。

然后,您将能够迭代 map 的键并根据这些 ID 提取每个学生和分数

已更新以满足要求

阅读更新的要求后,我注意到使用排序的映射而不是列表会更好。

基本上,我们将每个学生的姓名放入一个根据个人 ID 进行排序的映射中。然后,我们将每个列表放在根据 ID 键控的排序映射中的列表中

public class TestArraySort {

    public static void main(String[] args) {
        new TestArraySort();
    }

    public TestArraySort() {

        try {
            File file1 = new File("studentNames.txt");
            File file2 = new File("studentScores.txt");

            // Better to check for both files here, other wise it's just wasting time
            if (file1.exists() && file2.exists()) {
                // Create the sorted maps so that they are in scope...
                Map<Integer, String> mapStudents = new TreeMap<Integer, String>();
                Map<Integer, List<Double>> mapScores = new TreeMap<Integer, List<Double>>();

                Scanner input = null;
                try {
                    input = new Scanner(file1);
                    // Read the student information...
                    while (input.hasNext()) {
                        int id = input.nextInt();
                        String name = input.nextLine().trim();
                        mapStudents.put(id, name);
                    }
                    // Safty net
                } finally {
                    input.close();
                }

                try {
                    // Read the scores
                    input = new Scanner(file2);
                    while (input.hasNext()) {
                        int id = input.nextInt();
                        double score = input.nextDouble();

                        // If the list doesn't already exist, create it
                        List<Double> scores = mapScores.get(id);
                        if (scores == null) {
                            scores = new ArrayList<Double>(25);
                            mapScores.put(id, scores);
                        }
                        scores.add(score);
                    } /// end while
                    // Safty net
                } finally {
                    input.close();
                }

                // Dump the results
                System.out.println("+------------+----------------------+------+");
                for (Integer id : mapStudents.keySet()) {
                    // Display the student results
                    String name = mapStudents.get(id);
                    System.out.printf("| %10d | %-20s | ", id, name);
                    List<Double> scores = mapScores.get(id);
                    if (scores.size() > 0) {

                        // Sort the list
                        Collections.sort(scores);
                        // Reverse the list so that the scores are now in order from highest to lowest
                        // Sure, I could create a reverse comparator when I sort it, but
                        // I'm lazy...
                        Collections.reverse(scores);

                        // Print the first score...
                        System.out.printf("%4.1f |\n", scores.get(0));
                        // Print the remaining scores...
                        for (int index = 1; index < scores.size(); index++) {
                            System.out.printf("| %10s | %-20s | %4.1f |\n", "", "", scores.get(index));
                        }

                    } else {

                        System.out.println("00.0 |");

                    }
                    System.out.println("+------------+----------------------+------+");

                }

            } // end if(file2.exists)    }

        } catch (IOException exp) {
            exp.printStackTrace();
        }
    }
}

哪个产生

+------------+----------------------+------+
|       3305 | Smith Henry          | 92.0 |
|            |                      | 89.0 |
|            |                      | 78.5 |
+------------+----------------------+------+
|       5555 | Eddy Olivia          | 95.5 |
|            |                      | 90.5 |
|            |                      | 85.0 |
+------------+----------------------+------+
|       8915 | Johnson Luke         | 98.5 |
|            |                      | 95.5 |
|            |                      | 82.0 |
+------------+----------------------+------+

关于java - 如何在 Java 中比较和排序两个数组列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13115012/

相关文章:

java - 如何在 Retrofit for Android 中处理可选的 JSON 字段?

JAVA,setter 没有将发送到我的构造函数程序的值返回零

java - 将注释工作的结果传递给注释方法

java - 响应后立即请求?

java - 即使文件存在也无法读取 InputStream

java - 遍历 Java 中的链表?

java - "boilerplate comments?"有什么值(value)吗

java - 基于配置属性中的集合是否为空的 Spring Boot 条件

java - JAXB 为非根元素提供命名空间

java - RxJava 忽略 onNext