Concatenate Optional Lists

后端 未结 3 1387
不思量自难忘°
不思量自难忘° 2021-01-14 10:49

I have three Optional> which have to be combined and returned. I tried to use Optional.map() and flatmap() but was not successful.

         


        
相关标签:
3条回答
  • 2021-01-14 11:01

    I suggest that you don’t want to return an Optional from your method. In case there are no records in any of the three entity lists, the caller would prefer just to have an empty list.

    public List<Entity> getRecords() {
        return Stream.of("1", "2", "3")
                .map(repo::findAllByStatus)
                .flatMap(el -> el.map(List::stream).orElse(Stream.empty()))
                .collect(Collectors.toList());
    }
    

    A couple of the other answers use isPresent and get. They are low-level, and we don’t need them here.

    We don’t absolutely need the stream operation, though. Here’s a possibility without it:

    public List<Entity> getRecords() {
        List<Entity> concatenation = new ArrayList<>();
        repo.findAllByStatus("1").ifPresent(concatenation::addAll);
        repo.findAllByStatus("2").ifPresent(concatenation::addAll);
        repo.findAllByStatus("3").ifPresent(concatenation::addAll);
        return concatenation;
    }
    
    0 讨论(0)
  • 2021-01-14 11:10

    Something like :

    return Optional.of(Stream.of(entity1.orElse(new ArrayList<>()), entity2.orElse(new ArrayList<>()), entity3.orElse(new ArrayList<>()))
                .flatMap(List::stream)
                .collect(Collectors.toList()));
    

    or rather more readable as :

    return Optional.of(Stream.of(entity1, entity2, entity3)
            .filter(Optional::isPresent)
            .map(Optional::get)
            .flatMap(List::stream)
            .collect(Collectors.toList()));
    
    0 讨论(0)
  • 2021-01-14 11:10

    It gets easier when you use a stream:

    return Stream.of(entity1, entity2, entity3)
            .filter(Optional::isPresent)
            .map(Optional::get)
            .flatMap(List::stream)
            .collect(Collectors.collectingAndThen(Collectors.toList(), Optional::of));
    

    Important to note that this optional won't ever be empty. It will contain at least an empty list, which defeats the purpose of using optionals. When using Collection types as return types, Optional are not really used because it's recommended to return an empty collection where an empty optional would be used.

    So I would just change the method's return type to List and let the stream return an empty list when no input optional is present.

    0 讨论(0)
提交回复
热议问题