Java Redis有序集合案例怎么排序

wen java案例 27

本文目录导读:

Java Redis有序集合案例怎么排序

  1. 基本概念
  2. 基础示例代码
  3. 高级排序操作
  4. 实际应用案例
  5. 常用排序方法总结
  6. 性能提示

我来详细介绍 Java 中 Redis 有序集合(Sorted Set)的排序方法和案例。

基本概念

有序集合中的每个元素都有一个分数(score),Redis 根据分数进行排序:

  • 默认按分数从小到大排序
  • 分数相同的元素按字典序排序

基础示例代码

添加数据和查询

import redis.clients.jedis.Jedis;
import redis.clients.jedis.Tuple;
import java.util.Set;
public class RedisSortedSetExample {
    public static void main(String[] args) {
        // 连接Redis
        Jedis jedis = new Jedis("localhost", 6379);
        // 1. 添加学生成绩(分数:score,成员:member)
        jedis.zadd("student_scores", 85.5, "张三");
        jedis.zadd("student_scores", 92.0, "李四");
        jedis.zadd("student_scores", 78.0, "王五");
        jedis.zadd("student_scores", 95.5, "赵六");
        jedis.zadd("student_scores", 88.0, "小明");
        // 2. 正序查询(从小到大)
        System.out.println("=== 分数从小到大排序 ===");
        Set<String> scoresAsc = jedis.zrange("student_scores", 0, -1);
        for (String member : scoresAsc) {
            Double score = jedis.zscore("student_scores", member);
            System.out.println(member + ": " + score);
        }
        // 3. 倒序查询(从大到小)
        System.out.println("\n=== 分数从大到小排序 ===");
        Set<String> scoresDesc = jedis.zrevrange("student_scores", 0, -1);
        for (String member : scoresDesc) {
            Double score = jedis.zscore("student_scores", member);
            System.out.println(member + ": " + score);
        }
        jedis.close();
    }
}

高级排序操作

带分数的排序查询

public class AdvancedSortedSetExample {
    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);
        // 1. 查询带分数的结果
        System.out.println("=== 带分数的正序查询 ===");
        Set<Tuple> tuplesAsc = jedis.zrangeWithScores("student_scores", 0, -1);
        for (Tuple tuple : tuplesAsc) {
            System.out.println(tuple.getElement() + ": " + tuple.getScore());
        }
        // 2. 按分数范围查询
        System.out.println("\n=== 分数在80-90之间的学生 ===");
        Set<Tuple> rangeByScore = jedis.zrangeByScoreWithScores("student_scores", 80, 90);
        for (Tuple tuple : rangeByScore) {
            System.out.println(tuple.getElement() + ": " + tuple.getScore());
        }
        // 3. 获取排名信息
        System.out.println("\n=== 排名信息 ===");
        String[] students = {"张三", "李四", "王五"};
        for (String student : students) {
            // 正序排名(从0开始)
            Long rank = jedis.zrank("student_scores", student);
            // 倒序排名
            Long revRank = jedis.zrevrank("student_scores", student);
            System.out.println(student + " - 正序排名: " + (rank + 1) + ", 倒序排名: " + (revRank + 1));
        }
        jedis.close();
    }
}

实际应用案例

游戏排行榜

public class GameLeaderboard {
    private Jedis jedis;
    private static final String LEADERBOARD_KEY = "game:leaderboard";
    public GameLeaderboard() {
        this.jedis = new Jedis("localhost", 6379);
    }
    // 更新玩家分数
    public void updateScore(String playerId, double score) {
        jedis.zadd(LEADERBOARD_KEY, score, playerId);
    }
    // 获取排行榜(前N名)
    public List<PlayerScore> getTopPlayers(int topN) {
        Set<Tuple> topPlayers = jedis.zrevrangeWithScores(LEADERBOARD_KEY, 0, topN - 1);
        List<PlayerScore> result = new ArrayList<>();
        int rank = 1;
        for (Tuple tuple : topPlayers) {
            result.add(new PlayerScore(rank++, tuple.getElement(), tuple.getScore()));
        }
        return result;
    }
    // 获取玩家排名和分数
    public PlayerScore getPlayerRank(String playerId) {
        Double score = jedis.zscore(LEADERBOARD_KEY, playerId);
        Long rank = jedis.zrevrank(LEADERBOARD_KEY, playerId);
        if (score != null && rank != null) {
            return new PlayerScore(rank.intValue() + 1, playerId, score);
        }
        return null;
    }
    // 玩家分数实体类
    static class PlayerScore {
        private int rank;
        private String playerId;
        private double score;
        public PlayerScore(int rank, String playerId, double score) {
            this.rank = rank;
            this.playerId = playerId;
            this.score = score;
        }
        @Override
        public String toString() {
            return String.format("第%d名: %s (分数: %.1f)", rank, playerId, score);
        }
    }
    public static void main(String[] args) {
        GameLeaderboard leaderboard = new GameLeaderboard();
        // 模拟玩家数据
        leaderboard.updateScore("player_001", 9500);
        leaderboard.updateScore("player_002", 8800);
        leaderboard.updateScore("player_003", 10200);
        leaderboard.updateScore("player_004", 7600);
        leaderboard.updateScore("player_005", 9900);
        // 获取前3名
        System.out.println("=== 游戏排行榜 TOP 3 ===");
        List<PlayerScore> top3 = leaderboard.getTopPlayers(3);
        for (PlayerScore ps : top3) {
            System.out.println(ps);
        }
        // 查询特定玩家
        System.out.println("\n=== 玩家排名查询 ===");
        PlayerScore player = leaderboard.getPlayerRank("player_003");
        if (player != null) {
            System.out.println(player);
        }
    }
}

常用排序方法总结

方法 描述
zadd(key, score, member) 添加元素
zrange(key, start, stop) 正序获取
zrevrange(key, start, stop) 倒序获取
zrangeWithScores(key, start, stop) 正序获取(含分数)
zrevrangeWithScores(key, start, stop) 倒序获取(含分数)
zrangeByScore(key, min, max) 按分数范围获取
zrank(key, member) 获取正序排名
zrevrank(key, member) 获取倒序排名

性能提示

  1. 使用带分数的查询:使用 WithScores 方法减少额外的查询
  2. 合理设置范围:避免一次获取过多数据
  3. 分数设计:使用整数或简单小数,避免浮点数精度问题

通过以上示例,你可以根据业务需求灵活使用 Redis 有序集合的排序功能。

抱歉,评论功能暂时关闭!