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

Viewed 281

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?

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());

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))));
Related