3

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 2

5

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());
Sign up to request clarification or add additional context in comments.

Comments

4

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

5 Comments

won't this give NullPointer for customerInfo ADDRESS value when it is null like I have mentioned in the question?
2nd solution is better, without filtering
Yeah this is surely better but not working for map when {ADDRESS=null}, Tried to add filter after compareKeys.stream() but still getting NullPointer.
which Map do you mean? see demo
Correct, the filter I was adding was causing problem. Thanks a lot!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.