Redisson_RMap/RSet系列
简介
RMap是基于Redis的分布式集合中的数据结构”映射Map“,是Redisson提供的一种高性能组件。
继承于接口 java.util.Map和java.util.concurrent.ConcurrentMap,所以不仅拥有了两者的功能,同时自身也提供了很多特有的方法
上菜
功能1:Rmap添加元素
实体类初始化:
/* 映射数据结构RMap的实体信息*/
@Data
@ToString
@EqualsAndHashCode
public class RMapDto implements Serializable {private Integer id; //idprivate String name; //名称//空的构造方法public RMapDto() {}//包括所有字段的构造方法public RMapDto(Integer id, String name) {this.id = id;this.name = name;}
}
/* 功能组件Map-RMap*/public void testRmapInit(){//定义存储于缓存中间件Redis的Keyfinal String key="myRedissonRMap";//构造对象实例RMapDto dto1=new RMapDto(1, "map1");RMapDto dto2=new RMapDto(2, "map2");RMapDto dto3=new RMapDto(3, "map3");RMapDto dto4=new RMapDto(4, "map4");RMapDto dto5=new RMapDto(5, "map5");RMapDto dto6=new RMapDto(6, "map6");RMapDto dto7=new RMapDto(7, "map7");RMapDto dto8=new RMapDto(8, "map8");//获取映射RMap功能组件实例,并采用多种不同的方式将对象实例添加进映射RMap中RMap<Integer, RMapDto> rMap=redissonClient.getMap(key);//正常的添加元素rMap.put(dto1.getId(), dto1);//异步的方式添加元素rMap.putAsync(dto2.getId(), dto2);//添加元素之前判断是否存在,如果不存在才添加元素;否则不添加rMap.putIfAbsent(dto3.getId(), dto3);//添加元素之前判断是否存在,如果不存在才添加元素;否则不添加 - 异步的方式rMap.putIfAbsentAsync(dto4.getId(), dto4);//正常的添加元素-快速的方式rMap.fastPut(dto5.getId(), dto5);//正常的添加元素-快速异步的方式rMap.fastPutAsync(dto6.getId(), dto6);//添加元素之前判断是否存在,如果不存在才添加元素;否则不添加-异步的方式rMap.fastPutIfAbsent(dto7.getId(), dto7);//添加元素之前判断是否存在,如果不存在才添加元素;否则不添加 - 异步快速的方式rMap.fastPutIfAbsentAsync(dto8.getId(), dto8);System.out.println("---往映射数据结构RMap中添加数据元素完毕---");}
功能2:Rmap取出元素
public void testRmapGet(){log.info("---从映射数据结构RMap中获取数据元素开始---");//定义存储于缓存中间件Redis的Keyfinal String key="myRedissonRMap";//获取映射RMap的功能组件实例//并采用多种不同的方式将对象实例添加进映射RMap中RMap<Integer, RMapDto> rMap=redissonClient.getMap(key);//遍历获取并输出映射RMap数据结构中的元素Set<Integer> ids=rMap.keySet();Map<Integer, RMapDto> map=rMap.getAll(ids);log.info("元素列表:{} ", map);//指定待移除的元素idfinal Integer removeId=6;rMap.remove(removeId);map=rMap.getAll(rMap.keySet());log.info("移除元素{}后的数据列表:{} ", removeId, map);//待移除的元素id列表final Integer[] removeIds=new Integer[]{1,2,3};rMap.fastRemove(removeIds);map=rMap.getAll(rMap.keySet());log.info("移除元素{}后的数据列表:{} ", removeIds, map);}
功能3:元素淘汰
允许针对一个map中的每个元素单独设定有效时间和最长闲置时间。
Redisson会额外开启一个定时的任务调度,定时扫描特定的数据元素是否已经到了存活时间。如果数据元素已经超过了指定的过期时间,则Redisson会将该数据元素从指定的数据结构RMap中移除,从而实现数据元素的淘汰功能。
RMapCache实例添加了4个实体对象,并为id为2和4的实体对象分别设置10秒和5秒的过期时间,之后获取、输出并打印数据结构RMap中所有的数据元素。理论上,当首次获取所有的数据元素时,程序将会输出打印4个实体对象;当程序等待5秒钟后,由于此时id为4的实体对象已经到了过期时间,因而此时数据结构 RMap中将只剩下3个数据元素;当程序继续等待10秒钟后,由于id为2的实体对象将到达过期时间,因而最终数据结构RMap中将只剩下2个数据元素,即id为1和3对应的实体对象。
/* 元素淘汰*/@SneakyThrowspublic void testEviction(){//定义存储于缓存中间件Redis的Keyfinal String key="myRedissonMapCache";//获取映射缓存RMapCache的功能组件实例-元素淘汰机制对应的实例RMapCache<Integer, RMapDto> rMap=redissonClient.getMapCache(key);//构造对象实例RMapDto dto1=new RMapDto(1, "map1");RMapDto dto2=new RMapDto(2, "map2");RMapDto dto3=new RMapDto(3, "map3");RMapDto dto4=new RMapDto(4, "map4");//将对象元素添加进MapCache组件中rMap.putIfAbsent(dto1.getId(), dto1);//将对象元素添加进MapCache组件中-有效时间TTL设置为10秒钟,即该数据元素存活时间为10秒rMap.putIfAbsent(dto2.getId(), dto2,10, TimeUnit.SECONDS);//将对象元素添加进MapCache组件中rMap.putIfAbsent(dto3.getId(), dto3);//将对象元素添加进MapCache组件中-有效时间TTL设置为5秒钟,即该数据元素存活时间为5秒rMap.putIfAbsent(dto4.getId(), dto4,5, TimeUnit.SECONDS);//首次获取MapCache组件的所有KeySet<Integer> set=rMap.keySet();//获取MapCache组件存储的所有元素Map<Integer, RMapDto> resMap=rMap.getAll(set);log.info("元素列表:{} ", resMap);//等待5秒钟-再获取查看MapCache存储的数据元素列表Thread.sleep(5000);resMap=rMap.getAll(rMap.keySet());log.info("等待5秒钟-元素列表:{} ", resMap);//等待10秒钟-再获取查看MapCache存储的数据元素列表Thread.sleep(10000);resMap=rMap.getAll(rMap.keySet());log.info("等待10秒钟-元素列表:{} ", resMap);}
输出:
元素列表:{1=RMapDto(id=1, name=map1), 4=RMapDto(id=4, name=map4), 2=RMapDto(id=2, name=map2), 3=RMapDto(id=3, name=map3)}
等待5秒钟-元素列表:{1=RMapDto(id=1, name=map1), 2=RMapDto(id=2, name=map2), 3=RMapDto(id=3, name=map3)}
等待10秒钟-元素列表:{1=RMapDto(id=1, name=map1), 3=RMapDto(id=3, name=map3)}
功能4:有序集合 RSortedSet
Redisson为RSet提供了不同功能特点的数据结构,包括有序集合功能组件SortedSet、计分排序集合功能组件ScoredSortedSet,以及字典排序集合功能组件LexSortedSet等。
有序集合功能组件SortedSet
Redisson的集合数据组件RSet实体信息:
@Data
@ToString
@EqualsAndHashCode
public class RSetDto implements Serializable {private Integer id; //id字段private String name; //名称private Integer age; //年龄大小private Double score; //成绩-得分//空的构造方法public RSetDto() {}//拥有部分字段的构造方法public RSetDto(Integer id, String name, Double score) {this.id = id;this.name = name;this.score = score;}//拥有部分字段的构造方法public RSetDto(Integer id, String name, Integer age) {this.id = id;this.name = name;this.age = age;}public RSetDto(Integer id, String name, Integer age, Double score) {this.id = id;this.name = name;this.age = age;this.score = score;}
}
自定义元素比较器:
//集合RSet数据组件的自定排序
public class RSetComparator implements Comparator<RSetDto>{/* 自定义排序的逻辑* @param o1 the first object to be compared.* @param o2 the second object to be compared.* @return*/@Overridepublic int compare(RSetDto o1, RSetDto o2) {//表示后添加的数据元素,如果age更大,则排得越前return o2.getAge().compareTo(o1.getAge());}
}
对【age】字段排序
//集合Set-保证元素的唯一性 -RSortedSetpublic void testRSet() throws Exception{//定义存储于缓存中间件Redis的Key//保证了元素的有序性final String key="myRedissonSortedSetV2";//创建对象实例RSetDto dto1=new RSetDto(1, "N1",20,10.0D);RSetDto dto2=new RSetDto(2, "N2",18,2.0D);RSetDto dto3=new RSetDto(3, "N3",21,8.0D);RSetDto dto4=new RSetDto(4, "N4",19,6.0D);RSetDto dto5=new RSetDto(5, "N5",22,1.0D);//定义有序集合SortedSet实例RSortedSet<RSetDto> rSortedSet=redissonClient.getSortedSet(key);//设置有序集合SortedSet的元素比较器rSortedSet.trySetComparator(new RSetComparator());//将对象元素添加进集合中rSortedSet.add(dto1);rSortedSet.add(dto2);rSortedSet.add(dto3);rSortedSet.add(dto4);rSortedSet.add(dto5);//查看此时有序集合Set的元素列表Collection<RSetDto> result=rSortedSet.readAll();log.info("此时有序集合Set的元素列表:{} ",result);}
输出:
此时有序集合Set的元素列表:[RSetDto(id=5, name=N5, age=22, score=1.0),RSetDto(id=3, name=N3, age=21, score=8.0),RSetDto(id=1, name=N1, age=20, score=10.0),RSetDto(id=4, name=N4, age=19, score=6.0),RSetDto(id=2, name=N2, age=18, score=2.0)]
功能5:计分排序集合功能组件ScoredSortedSet
在实际生产环境中可以用于实现积分排行榜、最近访问排行榜等功能。在实际生产环境中可以用于实现积分排行榜、最近访问排行榜等功能。
//集合Set--ScoredSortedSetpublic void testScoredSortedSet() throws Exception{//定义存储于缓存中间件Redis的Keyfinal String key="myRedissonScoredSortedSet";//创建对象实例RSetDto dto1=new RSetDto(1, "N1",10.0D);RSetDto dto2=new RSetDto(2, "N2",2.0D);RSetDto dto3=new RSetDto(3, "N3",8.0D);RSetDto dto4=new RSetDto(4, "N4",6.0D);//定义得分排序集合ScoredSortedSet实例RScoredSortedSet<RSetDto> rScoredSortedSet=redissonClient.getScoredSortedSet(key);//往得分排序集合ScoredSortedSet中添加对象元素rScoredSortedSet.add(dto1.getScore(), dto1);rScoredSortedSet.add(dto2.getScore(), dto2);rScoredSortedSet.add(dto3.getScore(), dto3);rScoredSortedSet.add(dto4.getScore(), dto4);//查看此时得分排序集合ScoredSortedSet的元素列表//可以通过SortOrder指定读取出的元素是正序还是倒序Collection<RSetDto> result=rScoredSortedSet.readSortAlpha(SortOrder.DESC);log.info("此时得分排序集合ScoredSortedSet的元素列表-从大到小:{} ", result);//获取对象元素在集合中的位置-相当于获取排名//得到的排序值是从0开始算的,可以加1log.info("获取对象元素的排名:对象元素={},从大到小排名={} ", dto1, rScoredSortedSet.revRank(dto1)+1);log.info("获取对象元素的排名:对象元素={},从大到小排名={} ", dto2, rScoredSortedSet.revRank(dto2)+1);log.info("获取对象元素的排名:对象元素={},从大到小排名={} ", dto3, rScoredSortedSet.revRank(dto3)+1);log.info("获取对象元素的排名:对象元素={},从大到小排名={} ", dto4, rScoredSortedSet.revRank(dto4)+1);//获取对象元素在排名集合中的得分log.info("获取对象元素在排名集合中的得分:对象元素={},得分={} ", dto1, rScoredSortedSet.getScore(dto1));log.info("获取对象元素在排名集合中的得分:对象元素={},得分={} ", dto2, rScoredSortedSet.getScore(dto2));log.info("获取对象元素在排名集合中的得分:对象元素={},得分={} ", dto3, rScoredSortedSet.getScore(dto3));log.info("获取对象元素在排名集合中的得分:对象元素={},得分={} ", dto4, rScoredSortedSet.getScore(dto4));}
输出:
2023-04-11 16:03:36.150 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 此时得分排序集合ScoredSortedSet的元素列表-从大到小:[RSetDto(id=4, name=N4, age=null, score=6.0), RSetDto(id=1, name=N1, age=null, score=10.0), RSetDto(id=3, name=N3, age=null, score=8.0), RSetDto(id=2, name=N2, age=null, score=2.0)]
2023-04-11 16:03:36.182 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素的排名:对象元素=RSetDto(id=1, name=N1, age=null, score=10.0),从大到小排名=1
2023-04-11 16:03:36.211 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素的排名:对象元素=RSetDto(id=2, name=N2, age=null, score=2.0),从大到小排名=4
2023-04-11 16:03:36.241 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素的排名:对象元素=RSetDto(id=3, name=N3, age=null, score=8.0),从大到小排名=2
2023-04-11 16:03:36.271 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素的排名:对象元素=RSetDto(id=4, name=N4, age=null, score=6.0),从大到小排名=3
2023-04-11 16:03:36.301 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素在排名集合中的得分:对象元素=RSetDto(id=1, name=N1, age=null, score=10.0),得分=10.0
2023-04-11 16:03:36.331 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素在排名集合中的得分:对象元素=RSetDto(id=2, name=N2, age=null, score=2.0),得分=2.0
2023-04-11 16:03:36.361 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素在排名集合中的得分:对象元素=RSetDto(id=3, name=N3, age=null, score=8.0),得分=8.0
2023-04-11 16:03:36.390 INFO 117164 --- [nio-9999-exec-2] c.e.f.m.redisson.rmap.RMapServiceImpl : 获取对象元素在排名集合中的得分:对象元素=RSetDto(id=4, name=N4, age=null, score=6.0),得分=6.0
Redisson底层默认是采用“正序”的方式对数据元素进行排序的,因而在读取集合中所有的数据元素时,可以通过指定SortOrder.DESC为“从大到小的排序”顺序获取指定的数据元素,指定SortOrder.ASC为“从小到大的排序”顺序获取相应的数据列表。除了可以获取集合中数据元素的“排名”之外,还可以获取特定的数据元素的得分,即只需要通过getScore()方法即可获取到相应的得分。