类似排行榜需求的实现

运营类的活动中,经常会有类似积分榜、排行榜的功能需求,实时的展现总的积分、排名,包括他们各自的基本信息,以及自己的积分排名等。

关系型DB对此的支持并不好。实现比较复杂而且会DB带来不小的压力。


之前对Redis Set操作使用比较多,包括smembers、scard、sadd、sdiff等。Redis的zset,即Sorted-Set,与set的区别在于zset加了一个分数(score)与之关联。成员按照分数进行排序。和set一样,成员必须唯一,但是分数可以重复。zset增删改时间复杂度为成员数量的对数,十分高效。


1. 使用API

<pre name="code" class="java">public class RedisUtils {
/**
   * 将 member及其 score加入到有序集 key当中.如 member已经是有序集的成员,那么更新这个 member的score,并通过重新插入这个member来保证其在正确的位置上.
   * 如果 key不存在,则创建一个空的有序集并执行ZADD操作。当 key存在但不是有序集类型时返回一个错误
   * @param key
   * @param score
   * @param member
   * @return 如果是添加的新成员返回1;如果是成员本来就存在并更新成功返回0
   */
  Long zadd(String key, double score, String member);
  /**
   * 为有序集key的成员member的score值加上增量increment
   * @param key
   * @param increment
   * @param member
   * @return 返回member成员的新score值
   */
  Double zincrby(String key, double increment, String member);
  /**
   * 返回有序集key中所有score值介于start与end之间(包括等于)的成员.成员按score值递增(从小到大)排列
   * @param key
   * @param start
   * @param end
   * @return
   */
  Set<Tuple> zrangeWithScores(final String key, final int start, final int end);
  /**
   * 返回有序集key中所有score值介于start与end之间(包括等于)的成员.成员按score值递减(从大到小)排列
   * @param key
   * @param start
   * @param end
   * @return
   */
  Set<Tuple> zrevrangeWithScores(final String key, final int start, final int end);
  /**
   * 返回有序集 key中,成员 member的 score值
   * @param key
   * @param member
   * @return
   */
  Double zscore(String key, String member);
  /**
   * 返回有序集key中成员member的排名.成员按 score值递增(从大到小)顺序排列
   * @param key
   * @param member
   * @return
   */
  Long zrevrank(String key, String member);
  /**
   * 移除多个元素
   * @param key
   * @param member
   * @return
   */
  Long zrem(String key, String... member);
}
 


2. 业务逻辑

  // fromPassport用户给toUser用户投了num票
  @Override
  public Map<String, Object> thumbsUp(String fromPassport, ProducerThumbsupUser toUser, int num) {


    logger.info(fromPassport + "-------------" + num);
    Map<String, Object> map = new HashMap<>();


    String toPassport = toUser.getPassport();


    ProducerThumbsupRecord producerThumbsupRecord =
        producerThumbsupRecordDao.getByFromAndToUser(fromPassport, toPassport);
    
    if (producerThumbsupRecord != null) {
      
      logger.info("producerThumbsupRecord" + producerThumbsupRecord);
      
      map.put("count", producerThumbsupRecord.getScore());
      map.put("already", true);


      return map;
    } else {
      producerThumbsupRecord = new ProducerThumbsupRecord();
      producerThumbsupRecord.setFromuser(fromPassport);
      producerThumbsupRecord.setTouser(toUser.getPassport());
      producerThumbsupRecord.setScore(num);
      producerThumbsupRecord.setCreatetime(new Date());
      int rtn = producerThumbsupRecordDao.save(producerThumbsupRecord);
      
      String userJson = JSON.toJSONString(toUser);

      double result = RedisUtils.zincrby(producerThumbsUpList, num, userJson);
      logger
          .info(
              "thumbsUp update fromPassport: {}, toPassport: {}, num: {}, userJson: {}, result: {}",
              fromPassport, toPassport, num, userJson, result);


      map.put("count", num);
      map.put("already", false);


      return map;
    }
  }

  // 排行榜
  @Override
  public List<ProducerThumbsupUserWithScore> getThumbsUpList() {


    List<ProducerThumbsupUserWithScore> list = new ArrayList<>();


    Set<Tuple> set = RedisUtils.zrevrangeWithScores(producerThumbsUpList, 0, 50);
    for (Tuple tuple : set) {
      logger.info(tuple.getScore() + "--------" + tuple.getElement());


      ProducerThumbsupUser user =
          JSONObject.parseObject(tuple.getElement(), ProducerThumbsupUser.class);
      int score = (int) tuple.getScore();
      list.add(new ProducerThumbsupUserWithScore(user, score));
    }


    return list;
  }
  // 用户的票数
  @Override
  public int getScore(ProducerThumbsupUser producerThumbsupUser) {


    String user = JSON.toJSONString(producerThumbsupUser);
    logger.info("user--------" + user);
    Double score = RedisUtils.zscore(producerThumbsUpList, user);
    if (score == null) {
      return 0;
    }
    logger.info("score--------" + score);
    return score.intValue();
  }

  // 用户的排名
  @Override
  public int getRank(ProducerThumbsupUser producerThumbsupUser) {


    String user = JSON.toJSONString(producerThumbsupUser);
    Long rank = RedisUtils.zrevrank(producerThumbsUpList, user);


    if (rank == null) {
      return 0;
    }


    return rank.intValue();
  }





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些思路和步骤: 1. 编写贪吃蛇游戏 您可以使用Java Swing或JavaFX编写贪吃蛇游戏。游戏的核心逻辑包括蛇的移动、食物的生成、碰撞检测等。在游戏结束时,您需要将玩家的得分以及玩家信息(如昵称)存储到数据库中。 2. 连接MySQL数据库 Java提供了多种方式来连接MySQL数据库,您可以使用JDBC API或者第三方库(如MyBatis)来进行数据库操作。首先需要在本地或者远程搭建MySQL数据库,并创建一个表来存储玩家信息和得分。表的结构可以类似如下: ``` CREATE TABLE player_score ( id INT PRIMARY KEY AUTO_INCREMENT, player_name VARCHAR(50), score INT ); ``` 3. 将游戏得分存储到数据库中 在游戏结束时,您需要将玩家的得分以及玩家信息(如昵称)插入到数据库中。插入数据库的代码可以类似如下: ```java String playerName = "Tom"; int score = 100; Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/snake_game", "root", "password"); PreparedStatement ps = conn.prepareStatement("INSERT INTO player_score (player_name, score) VALUES (?, ?)"); ps.setString(1, playerName); ps.setInt(2, score); ps.executeUpdate(); ``` 4. 查询排行榜数据并展示 您可以编写一个排行榜窗口,从数据库中查询得分排名前N的玩家信息并展示。查询排行榜的代码可以类似如下: ```java Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/snake_game", "root", "password"); Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT player_name, score FROM player_score ORDER BY score DESC LIMIT 10"); while (rs.next()) { String playerName = rs.getString("player_name"); int score = rs.getInt("score"); // TODO: 展示排行榜数据 } ``` 以上是大致的实现思路,您可以根据自己的需求进行具体实现

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值