【问题标题】:Comparing students according to score JAVA根据JAVA分数比较学生
【发布时间】:2016-08-04 22:11:54
【问题描述】:

我有一个学生班。该类有String name、int studentId 和int studentScore。我想根据studentcore比较ArrayList<Student> students的学生。这意味着如果“学生 1”和“学生 2”的学生分数相同,那么他们的排名将相同。我有一个设置排名的功能。但我不确定如何比较数组列表中的所有内容。

当我搜索比较 int 值时,我得到了结果:

How to properly compare two Integers in Java?

我认为最好的解决方案是使用比较器类函数。但我不确定如何做到这一点,因为我不确定比较器类的能力。我想到了循环让玩家通过该循环然后再次循环并进行比较。但这似乎不是一个好的解决方案。

我想要这个结果:

假设包含(name,studentscore)的学生数组是:

(kim, 12), (werder, 20), (ben, 32), (sara, 12)

我希望学生的排名是(如果 ASC 顺序):

kim: rank = 1
werder: 2
ben: 3
sara: 1

【问题讨论】:

  • 你想达到什么目的?按分数排序,还是按分数排序?请发布一个简单的输入示例、期望的结果以及到目前为止您尝试了什么。
  • 这种情况下会返回什么,是升序的第一个分数吗?
  • @SashaSalauyou 我已经更新了我的问题。希望它能提供更好的清晰度
  • 是的,现在很清楚了。请参阅我建议的答案,如何使用自定义比较器并按排序列表中的位置应用排名。

标签: java arraylist int comparator


【解决方案1】:

您应该使用 java Stream (Java 8)。 更好的方法来做到这一点。 您可以在以下位置找到一个非常好的示例:http://www.leveluplunch.com/java/tutorials/007-sort-arraylist-stream-of-objects-in-java8/

【讨论】:

    【解决方案2】:

    如果我理解正确,您希望能够根据studentScore 对您的ArrayList<Student> 进行排序。

    你可以让学生类实现Comparable()

    public class Student implements Comparable<Student> {
        private String name;
        private int studentId;
        private int studentScore;
    
    public int compareTo(Contact other) {
        return studentScore.compareTo(other.studentScore);
    }
    

    那你就可以了

    ArrayList<Student> students = new ArrayList<Student>;
    // Insert you students into the array
    // students.add(someStudent)
    Collections.sort(students);
    

    请注意,这是Comparable 接口,它要求您实现方法compareTo()。如果您想施加总排序,则只需要Comparator 接口,例如对没有某些自然排序的对象进行排序。

    然后应按升序对列表中的学生进行排序,以使列表中的第一个元素为“最小”。

    【讨论】:

      【解决方案3】:

      有两种方法可以处理您的问题。你可以让你的类实现Comparable接口,然后它会有一个方法compareTo()。但是您需要担心您的compareTo() 方法与equals() 方法一致。这意味着您将需要覆盖您的 equals() 和 hashCode() 方法。这可能有点过分了。

      另一种方法是创建自己的 Comparator 来实现接口Comporator。您需要做的就是实现方法int compare(T o1, T o2),然后使用Collections 的public static void sort(List list, Comparator c) 方法。 对数组进行排序后,只需遍历它并分配适当的等级就很容易了

      【讨论】:

        【解决方案4】:

        您可以先使用Comparator.somparing() 比较器按分数划分学生,然后遍历排序列表并应用排名,如下所示:

        Collection<Student> students =  // ... your collection of students
        
        // copy students to a new List
        List<Student> ordered = new ArrayList<>(students);
        
        // sort by score
        Collections.sort(ordered, Comparator.comparing(Student::getScore));
        
        // set rank 1 to first item, i. e. having the lowest score
        int rank = 1;
        ordered.get(0).setRank(rank);
        for (int i = 1; i < ordered.size(); i++) {
            // increment rank only if score changed
            // in order to apply same ranks to same scores
            if (ordered.get(i).getScore() != ordered.get(i - 1).getScore())
                rank++;
            ordered.get(i).setRank(rank);
        }
        

        如果您需要将较低的排名分配给较高的分数,只需将.reversed() 应用于比较器:

        Collections.sort(ordered, Comparator.comparing(Student::getScore).reversed());
        

        要在 Java 1.8 之前的版本中创建比较器,您需要实例化一个匿名的 Comparator,其中实现了 .compare() 方法:

        Comparator<Student> cmp = new Comparator<Student>() {
            @Override
            public int compare(Student s1, Student s2) {
                return s1.getScore().compareTo(s2.getScore());
            }
        }
        

        【讨论】:

        • 这正是我在阅读link 后计划做的事情:“此语言级别不支持方法参考”和comparing 处的红色文本说“无法解析方法比较()”我使用在 apk 版本 16 上运行的 android Studio。
        • @CookieMonster 表示您使用 1.8 之前的 Java。我将更新以展示如何在早期的 Java 中创建自定义比较器。
        • 我厌倦了解决方法,我在compareTo 收到红色文本说“无法解析方法 compareTo(int)”,这也可能是 java 版本问题吗?
        • 哦,我拼错了。如果分数为int,则应为s1.getScore() - s2.getScore()
        猜你喜欢
        • 2022-01-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-18
        • 2018-10-20
        • 1970-01-01
        • 1970-01-01
        • 2022-01-20
        相关资源
        最近更新 更多