本文目录导读:

我来详细介绍 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) |
获取倒序排名 |
性能提示
- 使用带分数的查询:使用
WithScores方法减少额外的查询 - 合理设置范围:避免一次获取过多数据
- 分数设计:使用整数或简单小数,避免浮点数精度问题
通过以上示例,你可以根据业务需求灵活使用 Redis 有序集合的排序功能。