排名方法可用于分数排名,购买量排名等排名计算

3 篇文章 0 订阅


一、排名算法

1.代码如下:

package com.yunhenedu.core.utils.rank;

import com.yunhenedu.core.exception.BusinessException;
import com.yunhenedu.core.exception.ResultEnum;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 描述  排名工具类
 *
 * @author gx
 * @version 1.0
 * @date 2022/05/10 10:36:07
 */
public class RankUtils {

    public static void main(String[] args) {
        List<Integer> scoreList = new ArrayList<>();
        scoreList.add(1);
        scoreList.add(1);
        scoreList.add(2);
        scoreList.add(3);
        scoreList.add(3);
        List<Map<String, Integer>> scoreRankOneList = getScoreRankOneList(scoreList, 1, 6);
        List<Map<String, Integer>> scoreRankTwoList = getScoreRankTwoList(scoreList, 1, 6);
        System.out.println(scoreRankOneList);
        System.out.println(scoreRankTwoList);
    }


    /**
     * 描述  方法二  该方法可用于分数排名,购买量排名等排名计算
     * 举例: 数据  [1,2,2,3,3]
     * 输出名次如下:
     * 第一名:3,3
     * 第二名;无   第二个人在第一名里 该位置空
     * 第三名:2,2
     * 第四名:无  第四个人在第三名 该位置空
     * 第五名:1
     *
     * @param scoreList 进行排名的分数集合
     * @param startRank 开始名次
     * @param endRank   结束名次
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Integer>> 返回分数、分数对应的名次
     * @author gx
     * @date 2022/5/10 10:45:04
     * @version 1.0
     */
    public static List<Map<String, Integer>> getScoreRankTwoList(List<Integer> scoreList, Integer startRank, Integer endRank) {
        Map<Integer, Integer> scoreRankMap = getScoreRankMap(scoreList);
        List<Map<String, Integer>> resultList = getScoreRankDataList(startRank, endRank, scoreRankMap);
        return resultList;
    }
    private static List<Map<String, Integer>> getScoreRankDataList(Integer startRank, Integer endRank, Map<Integer, Integer> scoreRankMap) {
        if (startRank < 0 || endRank < 0) throw new BusinessException(ResultEnum.ERROR, "输入名次不合法");
        List<Map<String, Integer>> resultList = new ArrayList<>();
        scoreRankMap.forEach((key, value) -> {//key:分数  value:名次
            System.out.println(key + ":" + value);
            if (value >= startRank && value <= endRank) {
                Map<String, Integer> map = new HashMap<>();
                map.put("score", key);//分数
                map.put(key.toString(), value);//分数对应的名次
                resultList.add(map);
            }
        });
        return resultList;
    }

    private static Map<Integer, Integer> getScoreRankMap(List<Integer> scoreList) {
        //分数倒序
        Collections.sort(scoreList, Collections.reverseOrder());
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < scoreList.size(); i++) {
            if (i == 0) {
                map.put(scoreList.get(0), (0 + 1));//分数对应的名次
            }
            if (!map.containsKey(scoreList.get(i))) {
                map.put(scoreList.get(i), (i + 1));//分数对应的名次
            }
        }
        return map;
    }

    /** 该方法可用于分数排名,购买量排名等排名计算
     * 描述  同分同名占名次,名次位置跳一位置  (调用入口)
     * 举例: 数据  [1,2,2,3,3]
     * 输出名次如下:
     * 第一名:3,3
     * 第二名;无   第二个人在第一名里 该位置空
     * 第三名:2,2
     * 第四名:无  第四个人在第三名 该位置空
     * 第五名:1
     *
     * @param scoreList 进行排名的分数集合
     * @param score   需要查询分数所在的名次
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Integer>> 分数对应的名次
     * @author gx
     * @date 2022/5/10 10:45:04
     * @version 1.0
     */
    public static Integer getRankByScore(List<Integer> scoreList, Integer score) {
        //分数倒序
        Collections.sort(scoreList, Collections.reverseOrder());
        Map<Integer, Integer> map = new HashMap<>();
        for (int i = 0; i < scoreList.size(); i++) {
            if (i == 0) {
                map.put(scoreList.get(0), (0 + 1));//分数对应的名次
            }
            if (!map.containsKey(scoreList.get(i))) {
                map.put(scoreList.get(i), (i + 1));//分数对应的名次
            }
        }
        return map.get(score);
    }

    /**  方法二  该方法可用于分数排名,购买量排名等排名计算
     * 描述  同分同名占名次,名次位置跳一位置  (调用入口)
     * 举例: 数据  [1,2,2,3,3]
     * 输出名次如下:
     * 第一名:3,3
     * 第二名;无   第二个人在第一名里 该位置空
     * 第三名:2,2
     * 第四名:无  第四个人在第三名 该位置空
     * 第五名:1
     *
     * @param scoreList 进行排名的分数集合
     * @param startRank 开始名次
     * @param endRank   结束名次
     * @return java.util.List<java.util.Map < java.lang.String, java.lang.Integer>> 返回分数、分数对应的名次
     * @author gx
     * @date 2022/5/10 10:45:04
     * @version 1.0
     */
    public static List<Map<String, Integer>> getScoreRankOneList(List<Integer> scoreList, Integer startRank, Integer endRank) {
        //分数倒序
        Collections.sort(scoreList, Collections.reverseOrder());
        //标记分数的名次(根据数组下标)
        List<Integer> rankList = tagScoreRank(scoreList);
        //封装返回的数据
        List<Map<String, Integer>> mapList = setScoreRankInfo(scoreList, rankList, startRank, endRank);
        //根据分数去重
        return mapList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
                -> new TreeSet<>(Comparator.comparing(po->po.get("score")))), ArrayList::new));
    }

    private static List<Integer> tagScoreRank(List<Integer> scoreList) {
        //标记分数的名次
        List<Integer> rendks = new ArrayList<>();
        for (int i = 0; i < scoreList.size(); i++) {
            Integer item = scoreList.get(i);
            if (i != 0) {
                Integer upItem = scoreList.get(i - 1);
                if (upItem.equals(item)) {
                    rendks.add(rendks.get(i - 1));
                } else rendks.add(i);
            } else {
                rendks.add(i);
            }
        }
        return rendks;
    }

    private static List<Map<String, Integer>> setScoreRankInfo(List<Integer> scoreList, List<Integer> rankList, Integer startRank, Integer endRank) {
        if (startRank < 0 || endRank < 0) throw new BusinessException(ResultEnum.ERROR, "输入名次不合法");
        List<Map<String, Integer>> resultList = new ArrayList<>();
        for (int i = startRank - 1; i <= endRank - 1 && i < rankList.size(); i++) {
            Integer score = scoreList.get(i);
            Map<String, Integer> map = new HashMap<>();
            map.put("score", score);//分数
            map.put(score.toString(), (rankList.get(i) + 1));//分数对应的名次
            resultList.add(map);
        }
        return resultList;
    }

}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值