记一次使用TreeSet集合添加List集合排序时数据丢失变少的踩坑记录

最近在一个老的java项目中发现使用TreeSet排序后数据变少的生产问题

项目中TreeSet集合排序的步骤如下

  1. 自定义对象实现Comparable接口,实现compareTo方法
  2. 通过数据库查询返回一个List(首先排查就是怀疑是不是SQL写错了)
  3. Set set = new TreeSet();
  4. set.addAll(List);

问题定位后发现是在实现compareTo方法时当要比较的对象字段有相同值是返回retrurn 0;在实现ArrayList集合排序时返回0不是很正常吗?是的,但是当用TreeSet时就有可能会出现这个诡异的问题。

原理:通过跟踪TreeSet源码发现,TreeSet中使用的TreeMap来存储对象,将TreeSet的元素作为Map的key,继续跟踪TreeMap的put方法源码当比compareTo返回值是0时,key值不会变化(实际是更新key对应的value,TreeSet的value是无意义的),也就是说当出现多个返回0的情况时TreeSet中只会放入第一个元素,后面的全都舍弃掉,源码比较简单,这里就不贴了。

总结:当使用TreeSet排序时,如果实现的compareTo方法中有返回0的情况时就会造成数据丢失

解决方案:解决方式也很简单,不要让有重复的排序出现就可以了,实际业务如果不能避免那就换一个排序方式

其实原理比较简单,也很容易忽略踩坑。

猜你喜欢

转载自blog.csdn.net/weixin_48470176/article/details/107476714