Is there any way to Stream the list --> map --> filter --> map back to original object type of list?
There is solution if we are doing it using foreach as below:
List<Query> updatedQueries = getUpdatedQueries();
List<Query> finalQueries = new ArrayList<>();
updatedQueries.forEach(query -> {
Period period = getPeriodRequest(query);
boolean isValidPeriod = periodService.validatePeriodicity(period);
if(isValidPeriod && isMandatory(period)){
finalQueries.add(query);
}
});
But is there any way to do it using following way ?
List<Query> updatedQueries = getUpdatedQueries();
List<Query> finalQueries = updatedQueries
.stream()
.map(this::getPeriodRequest) //returns the object of type Period
.filter(period->periodService.validatePeriodicity(period))
.filter(this::isMandatory)
//is any way we can map back to Query object (without any object translation function)
.collect(Collectors.toList());
Few Java examples to show you how to filter a Map with Java 8 stream API. With Java 8, you can convert a Map. entrySet() into a stream , follow by a filter() and collect() it.
Converting complete Map<Key, Value> into Stream: This can be done with the help of Map. entrySet() method which returns a Set view of the mappings contained in this map. In Java 8, this returned set can be easily converted into a Stream of key-value pairs using Set. stream() method.
That's all about how to use map and filter in Java 8. We have seen an interesting example of how we can use the map to transform an object to another and how to use filter to select an object based upon condition. We have also learned how to compose operations on stream to write code that is both clear and concise.
The filter() function of the Java stream allows you to narrow down the stream's items based on a criterion. If you only want items that are even on your list, you can use the filter method to do this. This method accepts a predicate as an input and returns a list of elements that are the results of that predicate.
Try this one
List<Query> finalQueries = updatedQueries
.stream().filter(query->{
Period period = getPeriodRequest(query);
return periodService.validatePeriodicity(period )&& isMandatory(period))
})
.collect(Collectors.toList());
You can expand the filter
as:
List<Query> finalQueries = updatedQueries
.stream()
.filter(query -> {
Period period = getPeriodRequest(query);
return periodService.validatePeriodicity(period) && isMandatory(period);
})
.collect(Collectors.toList());
First of all your actual result is of type List<Period> finalQueries
because of that map(this::getPeriodRequest)
. Simply use some "longer" lambdas:
updatedQueries.stream()
.filter(q -> periodService.validatePeriodicity(q.getPeriodRequest()))
.filter(q -> isMandatory(q.getPeriodRequest()))
.collect(Collectors.toList())
You can even compress those two filter
s into a single one and read q.getPeriodRequest()
only once if you really wanted to.
Or you could map to a SimpleEntry
for example:
updatedQueries.stream()
.map(x -> new SimpleEntry<>(x, x.getPeriodRequest()))
.filter(e -> periodService.validatePeriodicity(e.getValue()))
.filter(e -> isMandatory(e.getValue()))
.map(Entry::getKey)
.collect(Collectors.toList());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With