上一章我们对分布式缓存List与Hash的数据结构进行实战演练,能够清楚的了解使用List数据结构实现榜单的思想,还有使用Hash结构实现购物车添加商品、查看商品、清空购物车的实现。接下来咱们对Set集合这个数据结构进行实战分析,本次实战分成三部分。第一部分:Set用户画像去重,第二部分:Set集合关注、粉丝、共同好友,第三部分:SortedSet集合积分榜单的实现。
Set数据结构案例-大数据下用户画像标签去重
什么是用户画像?
用户画像,作为大数据的根基,它可以完美的抽象出一个用户的全貌,为更进一步、快速的对用户行为习惯进行分析。用户画像可以简单的理解成是海量数据的标签,根据用户的目标。行为和观点的差异,将他们区分成了不同的类型。比如:一个抖音用户一直喜欢看关于汽车类的视频,那么该用户就会被打上汽车的标签,接下来通过大数据的计算给该用户一直推关于汽车类型的视频。
用户画像的应用场景有哪些呢?
用户画像的应用场景很广泛,比如个性化的推荐、精准营销、金融风控、精细化运营等等,举个例子来理解用户画像的实际应用价值,比如淘宝里的猜你喜欢这个功能。用户画像通过多个维度之间进行计算的标签,来存储到每个人的用户画像里,这时候有些标签避免不了会重复,这时Set集合就可以很好的去重了。
编写画像去重案例
在项目的测试(test)目录下进行编写去重方法,运行该方法可以看出来set1的值和set2的值是一样的,并且set添加了一个同样的dog,是没有添加进去吗?并不是的,是因为添加的这个元素重复了,所以可以使用set数据结构实现用户的标签去重。
BoundSetOperations operations = redisTemplate.boundSetOps("user:tags:1");
operations.add("car","student","rich","guangdong","dog","rich");
Set<String> set1 = operations.members();
System.out.println(set1);
operations.remove("dog");
Set<String> set2 = operations.members();
System.out.println(set2);
return JsonData.buildSuccess();
案例实战-社交应用里面的关注、粉丝、共同好友案例
需求分析
相信小伙伴们在玩一些社交应用的时候,这里就拿新浪微博为例子。在新浪微博里可以对一些博主进行关注,你就会成为了别人的粉丝,他也成为了你的关注用户。当然别人也可以关注你,道理一样。这时你会发现,如果你和你的好友一起关注了同一个博主,那么你们就会有共同关注的博主。
public void testSet(){
BoundSetOperations operationLW = redisTemplate.boundSetOps("user:lw");
operationLW.add("A","B","C","D","E");
System.out.println("⽼王的粉丝:"+operationLW.members());
BoundSetOperations operationXD = redisTemplate.boundSetOps("user:xd");
operationXD.add("A","B","F","G","H","J");
System.out.println("⼩D的粉丝:"+operationXD.members());
//差集
Set lwSet = operationLW.diff("user:xd");
System.out.println("⽼王的优势:"+lwSet);
//差集
Set xdSet = operationXD.diff("user:lw");
System.out.println("⼩滴的优势:"+xdSet);
//交集
Set interSet = operationLW.intersect("user:xd");
System.out.println("共同好友:"+interSet);
//并集
Set unionSet = operationLW.union("user:xd");
System.out.println("两个⼈的并集:"+unionSet);
//⽤户A是否是 ⽼王 的粉丝
boolean flag = operationLW.isMember("A");
System.out.println(flag);
}
通过上面的例子可以清楚的了解到使用Set集合的差集(我有的你没有的)、交集(我和你共同拥有的)、并集(我的全部与你的全部结合在一起)。通过上面的实战内容就可以实现共同好友等功能了。
案例实战-SortedSet开发用户积分实时榜单
需求分析
在现在一些市面的游戏上,必不可少就是一个游戏排行榜了,在上面我们有用过List数据结构实现了非实时的榜单,这里我们会使用SortedSet实现实时的榜单。一般排行榜我们一般都是读多写少,可以对master进行写入操作,然后使用多个slave进行读取操作。有一点要注意一下,如果存储对象的时候呢要重新HashCode与Equals的方法。
在VO类创建一个UserPointVO类
public class UserPointVO {
public UserPointVO(String username, String phone) {
this.username = username;
this.phone = phone;
}
private String username;
private String phone;
}
//set get方法略
//重写HashCode与equals方法 略
模拟榜单所需要的数据在Test类里添加
@Test
void testData() {
UserPointVO p1 = new UserPoint("⽼王","13113");
UserPointVO p2 = new UserPoint("⽼A","324");
UserPointVO p3 = new UserPoint("⽼B","242");
UserPointVO p4 = new UserPoint("⽼C","542345");
UserPointVO p5 = new UserPoint("⽼D","235");
UserPointVO p6 = new UserPoint("⽼E","1245");
UserPointVO p7 = new UserPoint("⽼F","2356432");
UserPointVO p8 = new UserPoint("⽼G","532332");
BoundZSetOperations<String, UserPointVO> operations = redisTemplate.boundZSetOps("point:rank:real");
operations.add(p1,123);
operations.add(p2,81);
operations.add(p3,218);
operations.add(p4,388);
operations.add(p5,888);
operations.add(p6,1888);
operations.add(p7,8);
operations.add(p8,18);
}
运行这个测试类代码后,在Redis中查看,会发现数据是从小到大进行排序的。一般榜单是从大到小排序的,这时我们应该如何实现呢?这时编写接口,当用户在获取积分后也要相应的加到榜单上。
在RankController里添加方法
//榜单从大到小排序
@RequestMapping("real_rank1")
public JsonData realRank1(){
BoundZSetOperations<String,UserPointVO> operations = redisTemplate.boundZSetOps("point:rank:real");
Set<UserPointVO> set = operations.reverseRange(0,-1);
return JsonData.buildSuccess(set)
}
//查看某个用户的排名
@RequestMapping("find_myrank")
public JsonData findRank1(String phone,String name){
BoundZSetOperations<String,UserPointVO> operations = redisTemplate.boundZSetOps("point:rank:real");
UserPointVO userPointVO = new UserPointVO(name,phone);
long rank = operations.reverseRank(userPointVO);
return JsonData.buildSuccess(++rank);
}
//给某个用户加积分
@RequestMapping("uprank")
public JsonData uprank(String phone,String name,int point){
BoundZSetOperations<String,UserPointVO> operations = redisTemplate.boundZSetOps("point:rank:real");
UserPointVO userPointVO = new UserPointVO(name,phone);
operations.incrementScore(userPointVO,point);
Set<UserPointVO> set = operations.range(0,-1);
return JsonData.buildSuccess(set);
}
//查看某个用户的积分
@RequestMapping("mypoint")
public JsonData mypoint(String phone,String name){
BoundZSetOperations<String,UserPointVO> operations = redisTemplate.boundZSetOps("point:rank:real");
UserPointVO userPointVO = new UserPointVO(name,phone);
double score = operations.score(userPointVO);
return JsonData.buildSuccess(set);
}
通过上面的代码就实现了从大到小排序的榜单,查看某个用户的排名,给某个用户加积分与查询某个用户积分的功能了。
本章小结:通过本章我们学习了Set集合的三种实战演练,第一种是使用Set集合去重做人物画像的功能,第二种是使用Set集合去做差集、交集、并集这方面可以使用在关注、粉丝、共同好友这种功能。第三种使用SortedSet集合实现了积分排行榜的功能,可以根据用户的积分进行由小到大或由大到小排序。可以看出Set集合的使用是非常广泛的。