问题代码
自定义Comparable
Set set = new TreeSet(自定义Comparable);
set.addAll(List); //List原来有5个,结果set只有4个,原因是List的compareTo返回的结果相同,导致后面的item被舍弃掉了。
原理
通过跟踪TreeSet源码发现,TreeSet中使用的TreeMap来存储对象,将TreeSet的元素作为Map的key,继续跟踪TreeMap的put方法源码当比compareTo返回值是0时,key值不会变化(实际是更新key对应的value,TreeSet的value是无意义的),也就是说当出现多个返回0的情况时TreeSet中只会放入第一个元素,后面的全都舍弃掉,源码比较简单,这里就不贴了。
总结:当使用TreeSet排序时,如果实现的compareTo方法中有返回0的情况时就会造成数据丢失。
解决方案:
- 方法一:不要让有重复的排序出现就可以了,实际业务如果不能避免那就换一个排序方式。
- 方法二:使用jdk8的list.stream().distinct().sort(排序规则).collect(Collectors.toList());
Stream#distinct是根据toString来进行去重,可以重写下List里的元素的toString方法。如果sort相同,也不会出现只会放入第一个元素,后面的全都舍弃掉的现象