Stream API中不同数值类型转换与比较问题求助
我来帮你排查下代码里的问题,然后给出靠谱的解决办法~
问题出在哪?
你的过滤条件始终返回false,主要是两个核心问题:
- 拿Stream对象直接和Long值比较:
sections.stream().map(Section::getId)返回的是一个Stream<Integer>管道,不是具体的ID集合,用equals去比这个Stream和部门的SectionId(Long类型),肯定不会相等。 - Long和Integer的equals不兼容:哪怕你拿到了Integer类型的Section ID,
Long.valueOf(1).equals(Integer.valueOf(1))也会返回false——因为包装类的equals会先检查类型是否一致,类型不同直接返回false。
怎么解决?
我们可以先把Section的ID统一转成Long类型,存到一个Set里(Set的查找效率比每次遍历Stream高太多),然后用Set的contains方法来做匹配,这样既解决了类型问题,又优化了性能。
修正后的完整代码:
private List<DepartmentInfo> retrieveLinkedDepartments(final Collection<Section> sections) { // 先把Section的Integer ID转成Long,存到Set里方便快速查找 Set<Long> targetSectionIds = sections.stream() .map(Section::getId) .map(Long::valueOf) // 统一转成Long,和部门的SectionId类型对齐 .collect(Collectors.toSet()); return this.departmentDao .findAll() .stream() .filter(department -> department.getSectionId() != null) .filter(department -> targetSectionIds.contains(department.getSectionId())) .map(this.departmentInfoMapper::map) .collect(Collectors.toList()); }
额外的小优化
- 如果
sections可能是空集合,可以提前判断直接返回空列表,省得做无用的Stream操作:if (sections.isEmpty()) { return Collections.emptyList(); } - 要是Section的ID可能为null,记得在转类型前加个过滤:
.filter(section -> section.getId() != null) .map(Section::getId)
这样改完之后,过滤逻辑就能正常工作啦,而且代码的可读性和性能都更好~
内容的提问来源于stack exchange,提问作者Stanislav Codes




