Java Stream将对象转换为降序整数集合失败问题
解决Stream去重后丢失原降序顺序的问题
这问题我之前处理过,太懂你的困扰了!你遇到的核心问题是:Collectors.toSet()默认返回的是无序的HashSet(少数场景下可能是TreeSet,但默认实现是HashSet),它完全不保留Stream流中元素的处理顺序;就算碰巧用了TreeSet,它默认也是按自然升序来排序的,所以才会得到2016、2017、2018的升序结果。
下面给你几个实用的解决方案,按需选择:
方案1:用LinkedHashSet保留原降序顺序
既然原列表已经是PostgreSQL按DESC排好的,我们只需要在去重时保留元素第一次出现的顺序就行,LinkedHashSet正好能做到这一点——它会按元素插入的顺序存储数据。
代码示例:
Set<Integer> yearsSet = someObjectList.stream() .map(SomeObject::getYears) .collect(Collectors.toCollection(LinkedHashSet::new));
这样处理后,yearsSet里的元素顺序就和原列表中年份第一次出现的顺序一致,也就是你想要的2018、2017、2016。
方案2:用distinct()+toList直接得到有序列表
如果你不是必须要用Set,只是需要一个唯一的降序年份集合,直接用distinct()方法配合toList()会更直观:
List<Integer> uniqueYearsDesc = someObjectList.stream() .map(SomeObject::getYears) .distinct() .collect(Collectors.toList());
distinct()方法会严格保留元素在流中第一次出现的顺序,所以结果自然就是降序的唯一年份列表。
方案3:用TreeSet强制降序排序
如果担心原列表的顺序可能不稳定(比如后续业务逻辑改动导致排序变化),可以直接用TreeSet并指定降序比较器,强制让集合按降序排列:
Set<Integer> yearsSet = someObjectList.stream() .map(SomeObject::getYears) .collect(Collectors.toCollection(() -> new TreeSet<>(Comparator.reverseOrder())));
这种方法不需要依赖原列表的顺序,不管输入是什么,最终都会得到一个降序的唯一年份Set。
内容的提问来源于stack exchange,提问作者Bronius Janonis
相关产品推荐
相关产品推荐

