简体   繁体   中英

Conversion/comparison of different numeric types inside streams

I'm having a problem with Stream API... again. The functionality I'm trying to implement isn't the hardest thing, but I'm having difficulties filtering since there are incompatible types and I don't how to make the comparison right. The idea is to get information about departments which the given sections are linked to.

department.getSectionId() returns Long while Section::getId is an Integer (which I can't change)

private List<DepartmentInfo> retrieveLinkedDepartments(final Collection<Section> sections) {
        return this.departmentDao
                .findAll()
                .stream()
                .filter(department -> department.getSectionId() != null)
                .filter(department -> department.getSectionId().equals(sections.stream().map(Section::getId)))                                           
                .map(this.departmentInfoMapper::map)
                .collect(Collectors.toList());
}

Of course the result of the main predicate is always false. I know the code is awful and I'm not defining conditions right, but I hope you get the idea. Maybe there's a possibility to somehow merge these collections or compare in a smart way.

Thank you in advance!

As of now you are comparing a Long and a Steam<Integer> which will always return false.

You can flip around your logic a little and use a mapToLong to convert the int's to Long 's:

private List<DepartmentInfo> retrieveLinkedDepartments(final Collection<Section> sections) {
    return this.departmentDao
               .findAll()
               .stream()
               .filter(department -> department.getSectionId() != null)
               .filter(department -> sections.stream()
                                 .mapToLong(Section::getId)                                     
                                 .anyMatch(department.getSectionId()::equals))                                           
               .map(this.departmentInfoMapper::map)
               .collect(Collectors.toList());
}

This will convert Section::getId to a Stream<Long> , and then filter through the Stream to see if any of the department.getSectionId equals the Id.

You're possibly looking for something like :

private List<DepartmentInfo> retrieveLinkedDepartments(final Collection<Section> sections) {
    Set<Long> sectionIds = sections.stream()
            .map(Section::getId)
            .map(Long::valueOf)
            .collect(Collectors.toSet()); // collect all the possible sectionIds
    return this.departmentDao
            .findAll()
            .stream()
            .filter(department -> department.getSectionId() != null)'
            // validate if the sectionIds include this department's section id or not
            .filter(department -> sectionIds.contains(department.getSectionId()))
            .map(this.departmentInfoMapper::map)
            .collect(Collectors.toList());
}

Offcourse the result of the main predicate is always false

That's because you've been comparing Long generated using department.getSectionId() with Stream<Integer> generated using sections.stream().map(Section::getId) , the comparison of these two types would always be unequal and hence the resultant false .

Edit : As pointed by Holger in comments, the code for preparation of the Set can be improved as:

Set<Long> sectionIds = sections.stream()
            .mapToLong(Section::getId)
            .boxed()
            .collect(Collectors.toSet());

In this line department.getSectionId().equals(sections.stream().map(Section::getId) you're comparing a Long against a Stream<Integer> which will always yield false.

instead map the Section ids to a Set<Long> and then use contains in the filter operation:

Set<Long> ids = sections.stream() // Stream<Section>
                        .map(Section::getId) //Stream<Integer>
                        .filter(Objects::nonNull) // remove potential null elements
                        .map(Integer::longValue) // Stream<Long>
                        .collect(Collectors.toSet()); //Set<Long>

return this.departmentDao
           .findAll()
           .stream()
           .filter(department -> department.getSectionId() != null)
           .filter(department -> ids.contains(department.getSectionId()))
           .map(this.departmentInfoMapper::map)
           .collect(Collectors.toList());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM