Redis实战(7)-SortedSet之认识有序集合(命令行与代码实战)

作者: 修罗debug
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。



摘要:缓存中间件Redis拥有许多丰富、重要且有趣的数据结构,前文介绍的字符串String、列表List和集合Set便是其中的佼佼者,本文以及后续篇章介绍的有序集合SortedSet和哈希Hash数据结构亦是如此,毫不夸张的说,当我们谈及Redis的应用场景时,这几种数据结构几乎都会涉及。本文我们将以命令行和代码的形式继续认识一下Redis的有序集合SortedSet

内容:在前面篇章中,我们给各位小伙伴介绍并实战了缓存中间件Redis的集合Set,介绍了并实战了其核心的几个特性,包括“唯一性/不重复性”和“无序性”,其中还介绍了一种比较典型的应用场景 ~ 利用集合Set实现“在线考试系统中考生如何获取随机、唯一且每份试卷的题目是乱序不一样的试题列表”。

而从本文开始,我们将给大家介绍 集合Set 的“孪生兄弟”,即有序集合SortedSet,这种数据结构延伸了集合Set的“元素唯一/不重复”的特性,但却有一点不同于集合Set,那就是SortedSet的成员元素具有“有序性”,而其“有序性”的实现是通过“添加成员时附带一个double类型的参数:分数”,从某种程度上讲,集合Set 和 有序集合SortedSet 可以说是一对“双胞胎”!

正是由于有序集合SortedSet的这两大特性,使得它本身也具有相当广泛的应用场景,比如“排行榜”便是其中相当常见的一种业务场景,我们将在后面的篇章中给各位小伙伴介绍如何利用有序集合SortedSet + 实际的代码实战“游戏充值排行榜”的实现!

本文我们将首先以命令行 + 代码的方式来认识并实战SortedSet,当作是对人家的一种认识吧!

对于有序集合SortedSet的常见命令,debug在这里给各位小伙伴贴了一张总览图,如下图所示,可以说是包含了SortedSet常见的诸多操作了:


下面我们再重点挑出几个使用相当频繁的命令吧!

(1)往集合添加N个成员,其中每个成员需要带上一个double类型的参数:分数

ZADD manScores 10 jack 11 debug 12 michael 13 mary 15 maria 20 xiuluo

返回值:(integer) 6

(2)返回集合当中成员的分数值:  

ZSCORE  manScores  jack

返回值:"10"

(3)获取集合中的成员总数:  

ZCARD manScores

返回值:(integer) 6

(4)为集合中指定的成员加上增量分数:  

ZINCRBY manScores 10 jack

返回值:"20"

(5)通过分数返回集合中指定区间内的成员:  

ZRANGEBYSCORE manScores 15 20 WITHSCORES

返回值:
1) "maria"
2) "15"
3) "jack"
4) "20"
5) "xiuluo"
6) "20"

(6)按照分数从低到高的排序-返回集合对应的所有成员:  

ZRANGE manScores 0 10 WITHSCORES

返回值:
1) "debug"
2) "11"
3) "michael"
4) "12"
5) "maria"
6) "15"
7) "jack"
8) "20"
9) "xiuluo"
10) "20"

(从高到低的排序:ZREVRANGE)

(7)返回集合中指定成员的排名(从低到高排名-排名从0开始):

ZRANK manScores maria

返回值:(integer) 2

(从高到低的排名:ZREVRANK)

(8)返回集合中指定分数区间内的成员-分数从高到低排序:

ZREVRANGEBYSCORE manScores 20 20

返回值:
1) "xiuluo"
2) "jack"

其余命令的实操各位小伙伴就自个儿去撸一撸了,只需要打开redis-cli.exe即可愉快的操作了!

最后,我们基于前文介绍的Spring Boot2.0搭建的项目写个Junit,即Java 单元测试方法,以实际代码的形式介绍并实战有序集合SortedSet相关命令所对应的的实际代码,如下所示:

    @Test
public void method4() {
log.info("----开始有序集合SortedSet测试");

final String key = "SpringBootRedis:SortedSet:10010";
redisTemplate.delete(key);

ZSetOperations<String,String> zSetOperations=redisTemplate.opsForZSet();
zSetOperations.add(key,"a",8.0);
zSetOperations.add(key,"b",2.0);
zSetOperations.add(key,"c",4.0);
zSetOperations.add(key,"d",6.0);

log.info("---有序集合SortedSet-成员数:{}",zSetOperations.size(key));
log.info("---有序集合SortedSet-按照分数正序:{}",zSetOperations.range(key,0L,zSetOperations.size(key)));
log.info("---有序集合SortedSet-按照分数倒序:{}",zSetOperations.reverseRange(key,0L,zSetOperations.size(key)));

log.info("---有序集合SortedSet-获取成员a的得分:{}",zSetOperations.score(key,"a"));
log.info("---有序集合SortedSet-获取成员c的得分:{}",zSetOperations.score(key,"c"));

log.info("---有序集合SortedSet-正序中c的排名:{} 名",zSetOperations.rank(key,"c")+1);
log.info("---有序集合SortedSet-倒序中c的排名:{} 名",zSetOperations.reverseRank(key,"c"));

zSetOperations.incrementScore(key,"b",10.0);
log.info("---有序集合SortedSet-按照分数倒序:{}",zSetOperations.reverseRange(key,0L,zSetOperations.size(key)));

zSetOperations.remove(key,"b");
log.info("---有序集合SortedSet-按照分数倒序:{}",zSetOperations.reverseRange(key,0L,zSetOperations.size(key)));

log.info("---有序集合SortedSet-取出分数区间的成员:{}",zSetOperations.rangeByScore(key,0,7));

log.info("---有序集合SortedSet-取出带分数的排好序的成员:");
Set<ZSetOperations.TypedTuple<String>> set=zSetOperations.rangeWithScores(key,0L,zSetOperations.size(key));
set.forEach(tuple -> log.info("--当前成员:{} 对应的分数:{}",tuple.getValue(),tuple.getScore()));

}

相关的方法以及API就不多做介绍了,在上面的日志log.info()里已经介绍得相当详细了!点击运行该单元测试方法,可以得到如下图的结果:


值得一提的是,建议各位小伙伴一定要将实际的代码操作 与 对应Dos下的命令行对应起来,只有这样子才能更彻底的理解并应用SortedSet.

好了,本篇文章我们就介绍到这里了,建议各位小伙伴一定要照着文章提供的样例代码撸一撸,只有撸过才能知道这玩意是咋用的,否则就成了“空谈者”!

对Redis相关技术栈以及实际应用场景实战感兴趣的小伙伴可以前往Debug搭建的技术社区的课程中心进行学习观看:https://www.fightjava.com/web/index/course/detail/12

其他相关的技术,感兴趣的小伙伴可以关注底部Debug的技术公众号,或者加Debug的微信,拉你进“微信版”的真正技术交流群!一起学习、共同成长!

补充:

1、本文涉及到的相关的源代码可以到此地址,check出来进行查看学习:

https://gitee.com/steadyjack/SpringBootRedis

2、目前Debug已将本文所涉及的内容整理录制成视频教程,感兴趣的小伙伴可以前往观看学习:https://www.fightjava.com/web/index/course/detail/12

3、关注一下Debug的技术微信公众号,最新的技术文章、课程以及技术专栏将会第一时间在公众号发布哦!