Java实现按分数排名,同分同名次

该博客主要介绍了两种Java实现分数排名的方法。第一种通过Stream API过滤、排序和分组计算学生的分数排名,并计算排名比例。第二种方法是将不同成绩保存到Map中,然后根据Map的键找到排名并存入实体。这两种方法都涉及到数据处理和排序算法在实际问题中的应用。
摘要由CSDN通过智能技术生成

解决方案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()));
});
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值