Java列表中的项目排名

时间:2014-01-17 20:26:37

标签: java list sorting

我试图写一个看似非常基本的计算。然而,经过多次尝试,它仍在踢我的屁股。

要解决的问题。我有<List>StudentGradesStudentGrades告诉我学生是谁以及学生.finalPercentage()是什么。现在我希望能够确定学生classStanding。如果分数如下所示:

  

100 99 98 98 98 97 96

然后排名应该看起来像

  

1 2 3 3 3 6 7

这就是我的尝试:

public final class RankingUtil{
  public static Integer getClassStanding(StudentGrades studentGrades, List<StudentGrades> allStudentGrades) {
    int classRank = 0;
    BigDecimal lastScore = BigDecimal.ZERO;
    BigDecimal secondLastScore = null;
    Collections.sort(allStudentGrades, new Comparator<StudentGrades>() {
      public int compare(StudentGrades o1, StudentGrades o2) {
        return -o1.getFinalPercentage().compareTo(o2.getFinalPercentage());
      }
    });

    for (StudentGrades sg : allStudentGrades) {
      if (!lastScore.equals(sg.getGradeSheetScoreTotalAchieved()) && lastScore.equals(secondLastScore)) {
        classRank++;
      }

      if (!lastScore.equals(sg.getGradeSheetScoreTotalAchieved())) {
        classRank++;
      }

      secondLastScore = lastScore;
      lastScore = sg.getGradeSheetScoreTotalAchieved();

      if (sg.equals(studentGrades)) {
        return classRank;
      }
    }

    return null;
  }
}

我确信这是我犯的一个简单的错误,但我遇到的问题是我最终得到以下等级:

  

1 2 3 3 3 5 6

您建议您如何跟踪个人应该居住的位置?

3 个答案:

答案 0 :(得分:2)

我不明白你为什么要拥有所有这些本地计数器。只需对您的列表进行排序,找到您给定的studentGrade的第一场比赛。

public static Integer getClassStanding(StudentGrade studentGrade, List<StudentGrade> allStudentGrades) {
    List<StudentGrade> localList = new ArrayList<>(allStudentGrades);
    Collections.sort(localList, new Comparator<StudentGrade>() {
        @Override public int compare(StudentGrade first, StudentGrade second) {
            return (second.getScore() <= first.getScore()) ? -1 : 1;
        }
    });

    for (int i = 0; i < localList.size(); i++) {
        if (localList.get(i).getScore() == studentGrade.getScore())
            return i+1;
    }
    return null;
}

另请注意,我制作了list-parameter的本地副本。您可能不希望为方法范围之外的所有人排序StudentGrades列表。

答案 1 :(得分:1)

我认为你过于复杂了。基本上,classRank只是列表中的位置,除非得分与之前相同,在这种情况下,等级也与之前相同。试试这个:

for (int i = 0; i < allStudentGrades.size(); i++) {
    StudentGrades sg = allStudentGrades.get(i);
    BigDecimal newScore = sg.getGradeSheetScoreTotalAchieved();
    if (lastScore.compareTo(newScore) != 0) {
        classRank = i + 1;
    }
    if (sg.equals(studentGrades)) {
        return classRank;
    }
    lastScore = newScore;
}

此外,您可能希望将这些值缓存在字典中,而不是每次重新计算它们。

答案 2 :(得分:0)

下面应该有效:

public final class RankingUtil {
    public static Integer getClassStanding(StudentGrades studentGrades, List<StudentGrades> allStudentGrades) {
        int classRank = 0;
        int rankCarryOver = 0;
        BigDecimal lastScore = BigDecimal.ZERO;
        Collections.sort(allStudentGrades, new Comparator<StudentGrades>() {
            public int compare(StudentGrades o1, StudentGrades o2) {
                return -o1.getFinalPercentage().compareTo(o2.getFinalPercentage());
            }
        });

    for (StudentGrades sg : allStudentGrades) {


        if (lastScore.compareTo(sg.getGradeSheetScoreTotalAchieved()) != 0) {
            classRank++;
            classRank = classRank + rankCarryOver;
            rankCarryOver = 0;
        } else {
            rankCarryOver++;
        }

        secondLastScore = lastScore;
        lastScore = sg.getGradeSheetScoreTotalAchieved();

        if (sg.equals(studentGrades)) {
            return classRank;
        }
    }

    return null;
}

}