Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle null while comparing maps using streams - Java?

I have 2 data structures with values like:

List<Map<String,String>> customerDirectory
[{NAME=ALEX BENSON, PHONE=012-12342, ADDRESS=123 MAIN ST, CITY=QUEENS, STATE=NY},
 {NAME=ZOYE ABEL, PHONE=012-12445, ADDRESS=123 WATERSIDE, CITY=WINDSOR, STATE=CT}]

and

Map<String,String> customerInfo
{NAME=ALEX BENSON, PHONE=012-12342, ADDRESS=123 MAIN ST}

I am trying to iterate through the customerDirectory to find if customerInfo has exact match in values for the keys - "NAME","PHONE","ADDRESS" so that I could find if the record is a duplicate.

So I have come up with:

List<String> compareKeys = Arrays.asList("NAME","PHONE","ADDRESS");

Function<Map<String,String>, String> getVal = mp -> compareKeys.stream().map(mp::get).map(String::trim).collect(Collectors.joining());

BiPredicate<Map<String,String>, Map<String,String>> checkDup = (mp1,mp2) -> getVal.apply(mp1).equals(getVal.apply(mp2));

boolean anyMatch = customerDirectory.stream().anyMatch(customer-> checkDup.test(customerInfo, customer));

But the customerInfo map can have value for ADDRESS as null for which I have tried:

BiFunction<Map<String, String>, String, String> handleNull = (mp, key) -> mp.get(key) == null ? " " : mp.get(key);

and I have used it in :

Function<Map<String,String>, String> getVal = mp -> compareKeys.stream().map(key->handleNull.apply(mp,key)).map(mp::get).map(String::trim).collect(Collectors.joining());

But I still end up getting NullPointerException which means I am missing the exact flow probably. Is there a better way to handle null values here?

like image 300
k92 Avatar asked Apr 07 '26 05:04

k92


2 Answers

If i correctly understood your question then you just want to find out is there any exact match or not, and you want to keep your answer in anyMatch. Please try to update your code with below one.

Function<Map<String, String>, String> getVal = mp -> 
    compareKeys.stream().map(mp::get).filter(Objects::nonNull).map(String::trim)
            .collect(Collectors.joining());
like image 192
Mr. Jain Avatar answered Apr 09 '26 18:04

Mr. Jain


You can do it in a better way I think.

boolean anyMatch = customerDirectory.stream()
         .anyMatch(m -> m.entrySet().stream()
           .filter(entry -> compareKeys.contains(entry.getKey()))
           .allMatch(entry -> entry.getValue().equals(customerInfo.get(entry.getKey()))));

or even more concise:

 boolean anyMatch =
            customerDirectory.stream()
                   .anyMatch(m -> compareKeys.stream()
                            .allMatch(key -> m.get(key).equals(customerInfo.get(key))));
like image 26
Hadi J Avatar answered Apr 09 '26 18:04

Hadi J



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!