简介
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; //id
private String name; //名称
//空的构造方法
public RMapDto() {
}
//包括所有字段的构造方法
public RMapDto(Integer id, String name) {
this.id = id;
this.name = name;
}
}
/**
* 功能组件Map-RMap
*/
public void testRmapInit(){
//定义存储于缓存中间件Redis的Key
final 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的Key
final 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);
//指定待移除的元素id
final 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对应的实体对象。
/**
* 元素淘汰
*/
@SneakyThrows
public void testEviction(){
//定义存储于缓存中间件Redis的Key
final 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组件的所有Key
Set<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
*/
@Override
public int compare(RSetDto o1, RSetDto o2) {
//表示后添加的数据元素,如果age更大,则排得越前
return o2.getAge().compareTo(o1.getAge());
}
}
对【age】字段排序
//集合Set-保证元素的唯一性 -RSortedSet
public 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--ScoredSortedSet
public void testScoredSortedSet() throws Exception{
//定义存储于缓存中间件Redis的Key
final 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开始算的,可以加1
log.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()方法即可获取到相应的得分。