I have an optional list of Integers, Optional<List<Integer>> id.
I have a list of many different people. List<People> people.
I have a filter method that takes takes the optional filter. The code calls the repository to get a list of people and, if the Optional list of id's is populated, will filter the people within the list against the id's. People.getId().
I want to use the steams API to avoid editing the original list. I have tried something like this
return people.stream()
.filter(p -> !request.getId().orElseGet(ArrayList::new).contains(p.getId()))
.collect(Collectors.toList());
The spec is.
- if no id's, return all
- if id's provided - filter
- if id's provided and no matches, return empty list
The above fails when the no id's match, it returns a full list.
Optional<List<Integer>> ids = Optional.of(Arrays.asList(1, 2, 3));
List<People> people = datasource...
List<People> filter (Optional < List < Integer >>> ids) {
List<People> confusion = people.steam(). ?
return confusion;
}
Any and all help is greatly appreciated!
if no id's, return all
Firstly, You just need an ||
condition. If the the Optional
is empty then the Optional.isPresent()
would be false
, so adding a !ids.isPresent()
before the ||
will return you all the items from the filter
as the ||
is a short-circuit operation as the condition on the left of the ||
is true
the entire condition will be true
.
if id's provided - filter
Secondly, the !
needs to be removed from your check and you need this check on the right of the ||
: ids.get().contains(p.getId())
to filter using the list of ids from the Optional
.
if id's provided and no matches, return empty list
Thirdly, if ids
is present then the second check will be evaluated as the first check !ids.isPresent()
becomes false
. The People
object will be checked if the id
matches with the list from the Optional
if nothing matches an empty list is returned.
So all three can be applied below:
List<People> list = people.stream()
.filter(p -> !ids.isPresent() || ( ids.get().isEmpty() || ids.get().contains(p.getId())))
.collect(Collectors.toList());
Also, it would be better if you would use an Optional<Set<Integer>>
instead of a Optional<List<Integer>>
, then contains()
would be constant time operation.