You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Stream API中不同数值类型转换与比较问题求助

我来帮你排查下代码里的问题,然后给出靠谱的解决办法~

问题出在哪?

你的过滤条件始终返回false,主要是两个核心问题:

  1. 拿Stream对象直接和Long值比较sections.stream().map(Section::getId)返回的是一个Stream<Integer>管道,不是具体的ID集合,用equals去比这个Stream和部门的SectionId(Long类型),肯定不会相等。
  2. 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

火山引擎 最新活动