解决方案1

/**
     * 计算分数排名
     * @param allFullScores
     */
    public void calculateScoreRank(List<StudentSubjectFullScoreDto> allFullScores) {
        Map<Long, StudentSubjectFullScoreDto> stuMap = allFullScores.stream().collect(Collectors.toMap(StudentSubjectFullScoreDto::getStuId, StudentSubjectFullScoreDto->StudentSubjectFullScoreDto));
        //过滤掉不统计的数据,这些数据不参与排名
        List<StudentSubjectFullScoreDto> scoreRankList = allFullScores.stream().filter(t -> t.getStatisticsStatus() == CommonConst.TYPE_STATISTICS_ENABLE).collect(Collectors.toList());
        //按学生单科成绩总分倒序排列
        scoreRankList.sort(Comparator.comparingDouble(StudentSubjectFullScoreDto::getSumScore).reversed());
        //按分数分组,统计个数
        Map<Double, Long> scoreMap = scoreRankList.stream().collect(Collectors.groupingBy(StudentSubjectFullScoreDto::getSumScore, Collectors.counting()));
        //初始值名次
        int rank = 1;
        double scoreRate = 1.0;	//此处不需要删除即可
        for (int i = 0; i < scoreRankList.size(); i++) {
            //得到相同分数的个数
            Long count = scoreMap.get(scoreRankList.get(i).getSumScore());
            scoreRate=new BigDecimal(scoreRankList.size() - rank).divide(new BigDecimal(scoreRankList.size()), 2, BigDecimal.ROUND_HALF_UP).doubleValue();
            if (count == 1) {
                StudentSubjectFullScoreDto copyDto = scoreRankList.get(i);
                StudentSubjectFullScoreDto sourceDto = stuMap.get(copyDto.getStuId());
                sourceDto.setScoreRank(rank++) ;
                sourceDto.setScoreRankRate(scoreRate);
            }else {
                //总分相同,名次相同
                for (int j = 0; j < count; j++) {
                    StudentSubjectFullScoreDto copyDto = scoreRankList.get(i+j);
                    StudentSubjectFullScoreDto sourceDto = stuMap.get(copyDto.getStuId());
                    sourceDto.setScoreRank(rank);
                    sourceDto.setScoreRankRate(scoreRate);
                }
                //排名还需要按人数顺序数他是第几个
                rank= (int) (rank+count);
                //连续n个相同的总分,排名一样
                i = (int) (i + count -1);
            }
        }
    }

解决方案2

/**
 * 排序:把不同成绩保存map中,最后实体类根据map的key找到排名 存入实体排名里面,前端取值。
 * @return
 */
public static Map<Double,Integer> rankScore(List<DeductPersonVO> stus) {
    Map<Double,Integer> map = new HashMap<>();
    List<Map.Entry<Double, List<DeductPersonVO>>> list = stus.stream().collect(Collectors.groupingBy(DeductPersonVO::getDeductScore)).entrySet()
            .stream().sorted((s1, s2) -> -Double.compare(s1.getKey(), s2.getKey())).collect(Collectors.toList());
    int index = 1;
    for (Map.Entry<Double, List<DeductPersonVO>> entry : list) {
 
        map.put(entry.getKey(),index);
        entry.getValue().forEach((s) -> System.out.print("  " + s.getDeductScore()));
        System.out.println();
        index++;
    }
    return map;
}

取出值存入实体

Map<Double,Integer> rankMap2 = rankScore(personList);
personList.stream().forEach(bean -> {
    bean.setRank(rankMap2.get(bean.getDeductScore()));
});
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐