Java实现排行榜功能

前言

最近项目需要开发一个排行榜功能,根据订单金额进行排名,同金额排名相同,不同则跳过,序列递增。

技术实现

  • MySQL
    通过SQL语句也能实现,不过SQL过于复杂,也不好维护。
SELECT
CASE
                
        WHEN
                @pre = final_score THEN
                        @pic + 0 
                        WHEN @pre := final_score THEN
                        @pic := @pic + 1 ELSE @pic := @pic + 1 
                END AS rank,
                rr.id registrationRecordId,
                rr.final_score AS number,
                us.userName,
                us.id userId,
                us.avatarImageURL headPortrait,
                CAST( p.`projectName` AS CHAR CHARSET UTF8 ) AS projectName,
                p.thumbnailURL,
                p.id projectId 
        FROM
                registration_record rr
                INNER JOIN `user` us ON rr.user_id = us.id
                INNER JOIN project p ON p.id = rr.project_id,(
                SELECT
                        @pre := NULL,
                        @pic := 0 
                ) AS init 
        WHERE
                rr.final_score IS NOT NULL 
                AND rr.competition_id = 41 
ORDER BY
        rr.final_score DESC

SQL类似这样,光从可读性就能劝退很多同学了。

  • Redis
    Redis也能实现排行榜功能,主要通过zset中的分数特性来实现,不过对于我的业务不太适合
  • SQL+Java代码
    通过SQL中的order by将查询的List根据某字段进行排好序,再将此List通过Java代码实现最终排行榜功能(推荐使用)
//伪SQL
select 
	a.schoolId
	a.schoolName,
	sum(a.amount)as count
	from a
	group by a.schoolId
	order by count desc

将需要排序的集合通过某字段排好序
Java代码

/**
     * 成交金额排名
     *
     * @param amountRankList
     * @return
     */
    private static List<AmountRankVO> amountRank(List<AmountRankVO> amountRankList) {
        amountRankList.sort((s1, s2) -> -Float.compare(s1.getCount(), s2.getCount()));
        int index = 0;
        int count = 0;

        int tmpSize = 0;
        Float lastCount = -1.00f;
        List<AmountRankVO> tmpAmountRankList = new ArrayList<>();
        for (int i = 0; i < amountRankList.size(); i++) {
            AmountRankVO amountRankVO = amountRankList.get(i);
            if (Double.compare(lastCount, amountRankVO.getCount()) != 0) {
                lastCount = amountRankVO.getCount();
                index = index + 1 + count;
                count = 0;
            }
            amountRankVO.setSequence(index);
            //相同并列,不同则跳过,序号一次递增
            if (tmpSize > 0) {
                if (amountRankVO.getCount() < amountRankList.get(tmpSize - 1).getCount()) {
                    amountRankVO.setSequence(tmpSize + 1);
                    index = tmpSize + 1;
                }
            }
            tmpAmountRankList.add(amountRankVO);
            tmpSize = tmpAmountRankList.size();
        }
        return tmpAmountRankList;
    }

如果想实现同金额相同排名,不出现序列自增,只需注释下面代码:

 //相同并列,不同则跳过,序号一次递增
            if (tmpSize > 0) {
                if (amountRankVO.getCount() < amountRankList.get(tmpSize - 1).getCount()) {
                    amountRankVO.setSequence(tmpSize + 1);
                    index = tmpSize + 1;
                }
            }

最后

最后我们看一下具体实现的效果,类似功能比如成绩排名,销量排名等都能适用
在这里插入图片描述

  • 4
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
实现排行榜功能,可以按照以下步骤: 1. 创建一个数据类,用于存储每个参与排行榜的对象的信息,包括名称、分数等。 2. 在程序创建一个List集合,将所有参与排行榜的对象的信息存储到List集合。 3. 对List集合进行排序,可以使用Collections.sort()方法,并实现Comparator接口的compare()方法,根据分数的高低来进行排序。 4. 将排好序的List集合的信息入到文件,可以使用FileOutputStream和ObjectOutputStream类实现。 5. 读取文件的信息,可以使用FileInputStream和ObjectInputStream类实现,将读取到的信息存储到List集合。 6. 将List集合的信息显示在控制台上,或者在GUI显示。 代码示例: ``` import java.io.*; import java.util.*; public class RankingList { public static void main(String[] args) { List<Player> players = new ArrayList<>(); players.add(new Player("Tom", 90)); players.add(new Player("Jerry", 80)); players.add(new Player("Mike", 70)); players.add(new Player("Bob", 85)); // 按照分数从高到低排序 Collections.sort(players, new Comparator<Player>() { @Override public int compare(Player o1, Player o2) { return o2.getScore() - o1.getScore(); } }); // 将排名信息入文件 try (ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("ranking.dat"))) { out.writeObject(players); } catch (IOException e) { e.printStackTrace(); } // 从文件读取排名信息 try (ObjectInputStream in = new ObjectInputStream(new FileInputStream("ranking.dat"))) { List<Player> rankingList = (List<Player>) in.readObject(); for (int i = 0; i < rankingList.size(); i++) { System.out.println("第" + (i+1) + "名:" + rankingList.get(i)); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); } } } class Player implements Serializable { private String name; private int score; public Player(String name, int score) { this.name = name; this.score = score; } public String getName() { return name; } public int getScore() { return score; } @Override public String toString() { return "Player{" + "name='" + name + '\'' + ", score=" + score + '}'; } } ``` 运行结果: ``` 第1名:Player{name='Tom', score=90} 第2名:Player{name='Bob', score=85} 第3名:Player{name='Jerry', score=80} 第4名:Player{name='Mike', score=70} ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值