Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Filtering data based on two conditions in java streams

I have the following code

public class Car {
    Long carNum;
    String carEngine;
}

The data in List object is as follows:

Car(carNum=1, carEngine=S02K), 
Car(carNum=1, carEngine=null), 
Car(carNum=2, carEngine=null),
Car(carNum=2, carEngine=S9K),
Car(carNum=3, carEngine=null)

How can I filter out data from the car object where

check for distinct carNum If there are more than one similar carNum then check where carEngine is not null and return the data in a list.

I am able to do the distinct carNum using

public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
}

in the following way:

carList.stream().filter(distinctByKey(Car::getCarNum)).collect(Collectors.toList());

The above code gets the distinct carNum but there is a very good chance that it will return the results with null carEngine.

How can I check where carEngine is not null along with distinct carNum combined.

NOTE: If there is only one distinct carNum without carEngine then I should return that row along with other rows.

For example: If the input data looks like this:

Car(carNum=1, carEngine=S02K), 
Car(carNum=1, carEngine=null), 
Car(carNum=2, carEngine=null),
Car(carNum=2, carEngine=S9K),
Car(carNum=3, carEngine=null)

then the output should be:

Car(carNum=1, carEngine=S02K), 
Car(carNum=2, carEngine=S9K),
Car(carNum=3, carEngine=null)

Please let me know. Thank you!

like image 348
Vamsi Avatar asked Feb 03 '26 21:02

Vamsi


1 Answers

I would recommend the toMap() collector with a merge function to select the one with a non-null engine:

carList.stream()
        .collect(Collectors.collectingAndThen(
                Collectors.toMap(
                        Car::getCarNum,
                        c -> c,
                        (a, b) -> a.getCarEngine() != null ? a : b),
                map -> new ArrayList<>(map.values())))

This way, if there's a carNum with only null engines, the first one will remain the final result.

like image 171
shmosel Avatar answered Feb 05 '26 13:02

shmosel



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!