英文:
How to handle null while comparing maps using streams - Java?
问题
我有两个数据结构,其值如下:
List<Map<String, String>> customerDirectory
```java
[{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}]
和
Map<String, String> customerInfo
{NAME=ALEX BENSON, PHONE=012-12342, ADDRESS=123 MAIN ST}
我正在尝试遍历customerDirectory
,以查找customerInfo
的值在键"NAME"
,"PHONE"
,"ADDRESS"
上是否有完全匹配,以便我可以判断记录是否重复。
所以我想到了:
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));
但是customerInfo
映射的ADDRESS
键可以具有值为null
,我尝试了:
BiFunction<Map<String, String>, String, String> handleNull = (mp, key) -> mp.get(key) == null ? " " : mp.get(key);
并将其用于:
Function<Map<String,String>, String> getVal = mp -> compareKeys.stream().map(key -> handleNull.apply(mp,key)).map(mp::get).map(String::trim).collect(Collectors.joining());
但我仍然会遇到NullPointerException
,这意味着我可能在流程中遗漏了一些内容。是否有更好的方法来处理这里的null
值?
<details>
<summary>英文:</summary>
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?
</details>
# 答案1
**得分**: 5
如果我正确理解您的问题,那么您只是想找出是否有任何精确匹配,而且您希望将答案保留在 **anyMatch** 中。请尝试使用以下代码进行更新。
```java
Function<Map<String, String>, String> getVal = mp ->
compareKeys.stream().map(mp::get).filter(Objects::nonNull).map(String::trim)
.collect(Collectors.joining());
英文:
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());
答案2
得分: 4
你可以用更好的方式来做,我认为。
boolean anyMatch = customerDirectory.stream()
.anyMatch(m -> m.entrySet().stream()
.filter(entry -> compareKeys.contains(entry.getKey()))
.allMatch(entry -> entry.getValue().equals(customerInfo.get(entry.getKey()))));
甚至更加简洁的写法:
boolean anyMatch =
customerDirectory.stream()
.anyMatch(m -> compareKeys.stream()
.allMatch(key -> m.get(key).equals(customerInfo.get(key))));
英文:
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))));
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论