redis 游戏排行榜的实现

一般排行榜信息 = 用户信息(头像-昵称) + 用户成绩(分数-排名)组成

因此我们可以使用 hash 这一数据结构存储用户信息,使用zset 这一数据结构存储用户成绩 。

// 用户成绩储存

SyncRedisUtils syncRedisUtils = new SyncRedisUtils(redisUtils);
syncRedisUtils.SyncRedis("light_game", Integer.valueOf(identity),lightGameSaveVO.getCoinTotal());
public class SyncRedisUtils {

    private RedisUtils redisUtils;
    public SyncRedisUtils(RedisUtils redisUtils) {
        this.redisUtils = redisUtils;

    }
    /**
     * 插入分数,根据分数和当前时间比较
     */
    因为公司用户在国外,所以选取的是美国时区
    public void SyncRedis(String key, Integer accountId, Integer value) {
        LocalDateTime nowTime = LocalDateTime.now(TimeZone.getTimeZone("America/Los_Angeles").toZoneId());
        long second = 9999999999L - nowTime.toInstant(ZoneOffset.of("-8")).toEpochMilli() / 1000;
        String dou = value + "." + second + "";
        double newCount = Double.parseDouble(dou);
        redisUtils.zAdd(key,accountId,newCount);
    }
}
// 用户信息储存
User user = userMapper.getUser(identity);
redisUtils.hset("light_game_user",identity,user); // 存入hash 
现在已经完成信息存储了,就要考虑实现排行榜了,下面是实现代码
//排行榜
List<RightGameRankVO.RankListVO> rankListVOS = new ArrayList<>();
Set<Object> reverseRange = redisUtils.reverseRange("light_game",0,49);
Map<String,Double> scoreMap = redisUtils.getZSetMembersAndScores("light_game",0,49);
if (reverseRange != null && reverseRange.size() > 0) {
    List<Object> reverseRangeList = new ArrayList<>(reverseRange);
    List<String> accountIdList = reverseRangeList.stream().map(String::valueOf).collect(Collectors.toList());
    for(String accountId : accountIdList){
        RightGameRankVO.RankListVO rankListDTO = new RightGameRankVO.RankListVO();
        User userOne = (User) redisUtils.hget("light_game_user",accountId);
        if(userOne == null){
        // 更新缓存
            userOne = userMapper.getUserByAccountId(accountId);
            redisUtils.hset("light_game_user",accountId,userOne);
        }
        rankListDTO.setRanking(RANK);
        Double coinTotal = scoreMap.get(accountId);
        rankListDTO.setCoinTotal((int) Math.floor(coinTotal));
        rankListDTO.setHeadPortrait(userOne.getHeadPortrait());
        rankListDTO.setNickName(userOne.getNickName());
        rankListVOS.add(rankListDTO);
        RANK++;
    }
}
public void zAdd(String key, Object accountId, Object value) {
        redisTemplate.opsForZSet().add(key, accountId, (Double) value);
}
/**
 * 获取用户排序
 * @param key 键
 * @param value 值
 * @return
 */
public Long  reverseRank(String key,  Object value) {
    Long userRank = redisTemplate.opsForZSet().reverseRank(key, value);
    return userRank;
}
/**
 * 获取范围排序
 * @param key 键
 * @return
 */

public Set<Object>  reverseRange(String key,  int start, int end) {
    Set<Object> reverseRange = redisTemplate.opsForZSet().reverseRange(key,  start,  end);
    return reverseRange;
}

// 可根据 你的需要封装

public Map<String,Double> getZSetMembersAndScores(String key,int start, int end) {
    ZSetOperations<String, Object> zSetOps = redisTemplate.opsForZSet();
    Map<String,Double> hash = new HashMap<>();
    Set<ZSetOperations.TypedTuple<Object>> zSetMembersAndScores =zSetOps.reverseRangeWithScores(key, start, end);
    for (ZSetOperations.TypedTuple<Object> tuple : zSetMembersAndScores) {
        String member = String.valueOf(tuple.getValue());
        Double score = tuple.getScore();
        hash.put(member,score);
    }
    return hash;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大毛族长

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值