10-分布式缓存实战-Set集合数据结构实战

366 阅读5分钟

上一章我们对分布式缓存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集合的使用是非常广泛的。