Reputation: 997
I am trying to refactor some code to return a list of optionals instead of an optional.
I have the following list in my class
private final List<Mapper<? extends Message>> mappers;
There is a private method that creates features for these mappers and returns a list of message
private List<Message> mapToFeature() {
mappers.stream()
.map(mapper -> mapper.createFeature())
.collect(Optionals.toList());
}
The Mapper interface looks like this:
public interface Mapper<T extends Message> {
Optional<T> createFeature();
}
The Optionals.toList()
method returns a Collector to filter present optionals into a List.
I want to change the interface (and all the corresponding classes) to return a list of optionals
public interface Mapper<T extends Message> {
List<Optional<T>> createFeature();
}
I do not have a method in the Optionals util to filter present options from multiple lists. How would I be able to do the same without making any changes to the util class?
Upvotes: 12
Views: 12064
Reputation: 2072
Since unable to understand your issue properly, it would be better if you will post your util class as well mean while see my go for this:
private List<Message> mapToFeature() {
return mappers.stream()
.map(mapper -> mapper.createFeature())
.flatMap(List::stream)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Optionals.toList());
}
Upvotes: 4
Reputation: 17487
Collect a stream of Optional
s to a list containing only the present values:
List<Optional<String>> someStrings = ...;
List<String> allPresentStrings = someStrings.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
Upvotes: 20
Reputation: 35141
Stream<Optional<T>> present = listOfOptionals.stream().filter(Optional::isPresent);
Stream<T> asTs = present.map(Optional::get);
// this is safe, because all remaining are present,
//convert Streams to Lists as usual with collect.
List<T> listTs = asTs.collect(Collectors.toList());
Upvotes: 0