redis ZSet 集合中取出 Set 对象 contains匹配不上
总结:基础很重要。
事情来由
我接手一个新项目,里面有个推送办理过程信息的调度
大概逻辑如下:
把受理时间转成zset分值,把受理id存到redis里面
然后Zset 支持根据传的分值 从小到大排序
他会从最先受理的开始监察办结情况 取出受理id 并且删除缓存
如果发现没办结的 会重新放到redis 给个当前时间的分值 避免死循环
部分代码展示
1.从set集合中获取并删除多个元素
public Set<Object> getAndRemoveZSet(String cacheKey, int size) {
if (StringUtils.isNotBlank(cacheKey)){
Set<Object> set = this.getZSetOperations().range(cacheKey, 0, size);
if (CollUtil.isNotEmpty(set)){
this.getZSetOperations().remove(cacheKey, set.toArray());
return set;
}
}
return null;
}
问题来了
这里就是获取前面的部分受理id
Set<Object> instIds = memoryDb.getAndRemoveZSet(KEY, size)
关键
processInstId 参数可以理解为已经办结的受理id
原来的同事是想如果已经办结 就在集合中移除 不重新放到redis里面
看起来好像没问题
但是就这行代码 导致出现千万垃圾数据(还好过程数据不太重要)
if (instIds.contains(processInstId))
产生这么多垃圾数据的原因就是他根本进不到里面
导致已经推了过程信息的数据 重新放到redis里面 然后重复推送
先看一段代码
public static void main(String[] args) {
Set<Object> instIdsX = new HashSet();
instIdsX.add(1);
instIdsX.add(Double.valueOf("2"));
instIdsX.add((long) 3);
instIdsX.add(("4"));
if (instIdsX.contains((long) 1)) {
System.out.println("long类型包含1");
}
if (instIdsX.contains("4")) {
System.out.println("String类型包含4");
}
if (instIdsX.contains("2")) {
System.out.println("String类型包含2");
}
if (instIdsX.contains((1))) {
System.out.println("int类型包含1");
}
if (instIdsX.contains(((long) 3))) {
System.out.println("long类型包含3");
}
if (instIdsX.contains((3))) {
System.out.println("int类型包含3");
}
}
控制台:
很明显就是 对象都要 与add进来的类型一样才能为ture
一起看看源码(大家可以自己debug看更清晰)
先看看HashSet的contains方法
就看getNode 是不是为空了 为空就是不包含嘛
这里想不为null 那不就是调用的传入对象的equals方法 为 true 嘛
在看下String重写的equals方法
(基本类型都是没重写equals方法 是 == 都是比较的内存地址)
结束!!!
总结:基础很重要。