Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any way to Stream Map Filter & Map back to original object in Java 8?

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());
like image 949
AshwinK Avatar asked May 08 '19 06:05

AshwinK


People also ask

How do you filter a stream map?

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.

Can we convert map into stream?

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.

Can we use filter and map together in Java?

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.

How do stream filters work?

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.


3 Answers

Try this one

List<Query> finalQueries = updatedQueries
    .stream().filter(query->{
        Period period = getPeriodRequest(query);
        return periodService.validatePeriodicity(period )&& isMandatory(period))
    })
    .collect(Collectors.toList());
like image 174
Hadi J Avatar answered Nov 15 '22 05:11

Hadi J


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());
like image 28
Naman Avatar answered Nov 15 '22 04:11

Naman


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 filters 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());
like image 22
Eugene Avatar answered Nov 15 '22 03:11

Eugene