简体   繁体   English

检查 map 是否仅包含一组键的 null 值

[英]Check whether a map contains not null values for only a set of keys

I have a map as below我有一个 map 如下

Map<String, String> myMap = new HashMap<>();
myMap.put("a", "Something");
myMap.put("b", null);
myMap.put("c", "more");

and a list,和一份清单,

List<String> myList = Arrays.asList("a","b");

I want to check, whether all the values in myMap with keys in myList are null我想检查 myMap 中带有 myList 键的所有值是否都是 null

I have created a method as follows and it works fine.我创建了一个如下方法,它工作正常。 I wanted to check whether we can achieve the same in one line of code using stream我想检查我们是否可以使用 stream 在一行代码中实现相同的目标

myMap.values().removeIf(Objects::isNull);

Map<String, String> resultMap = myList.stream().filter(myMap::containsKey).collect(Collectors.toMap(Function.identity(), myMap::get));
if(!resultMap.isEmpty()){
// Atleast one not null value is present in myMap with key in myList
}

Sure, simply check if all elements in the list match a non-null value from the map:当然,只需检查列表中的所有元素是否与 map 中的非空值匹配:

myList.stream().allMatch(x -> myMap.containsKey(x) && myMap.get(x) == null);
// or (more overhead, but you might prefer its expressivness):
myList.stream()
    .filter(myMap::containsKey)
    .map(myMap::get)
    .allMatch(Objects::isNull);

Or, if you consider "missing keys" to be equivalent to "having null":或者,如果您认为“缺少键”等同于“有空”:

myList.stream().map(myMap::get).allMatch(Objects:isNull);

Map.get specifies that keys that aren't present return null. Map.get指定不存在的键返回 null。 So you can filter out keys mapped to null or not mapped at all with just one null check.因此,您可以过滤掉映射到 null 或根本没有映射的键,只需一次 null 检查。

Map<String, String> resultMap = myList.stream()
    .filter(key -> myMap.get(key) != null)
    .collect(Collectors.toMap(Function.identity(), myMap::get));

If you don't need a resultMap it's even shorter with anyMatch如果您不需要resultMap ,则使用anyMatch会更短

myList.stream().allMatch(key -> myMap.get(key) != null)

Unlike myMap.values().removeIf(Objects::isNull) this will not modify the original map.myMap.values().removeIf(Objects::isNull)不同,这不会修改原始 map。

So, you've removed the entries having null values with this line:因此,您已使用此行删除了具有null的条目:

myMap.values().removeIf(Objects::isNull);

Fine, since keeping null-references in the collections an antipattern because these elements can't provide any useful information.很好,因为在 collections 中保留空引用是一种反模式,因为这些元素无法提供任何有用的信息。 So I consider this was your intention unrelated to checking if all the string in myList were associated with null (or not present).所以我认为这与检查myList中的所有字符串是否与null (或不存在)相关联无关。

Now to check whether myMap contain any of the elements from myList (which would automatically imply that the value mapped to such element is non-null ) you can create a stream over the contents of myList and check each element against the key-set of myMap :现在要检查myMap是否包含来自myList的任何元素(这将自动暗示映射到此类元素的non-null )您可以在 myList 的内容上创建一个myList并根据myMap键集检查每个元素:

boolean hasNonNullValue = myList.stream().anyMatch(myMap.keySet()::contains);

I suspect you might to perform some actions with such keys (if any).我怀疑您可能会使用此类(如果有)执行一些操作。 If so, then instead of performing a check provided above would make sense to generate a list of these keys :如果是这样,那么生成这些的列表而不是执行上面提供的检查是有意义的:

List<String> keysToExamine = myList.stream()
    .filter(myMap.keySet()::contains)
    .toList(); // for JDK versions earlier then 16 use .collect(Collectors.toList()) instead of toList()

Note : check elements of the list against the key-set , not the opposite, otherwise you might cause performance degradation.注意:对照key-set检查列表中的元素,而不是相反,否则可能会导致性能下降。

Stream#findAny and Optional#ifPresent Stream#findAnyOptional#ifPresent

It seems you want to perform some action if at least one non-null value is present in myMap with the corresponding key in myList .如果myList中至少存在一个非 null 值以及myMap中的相应键,您似乎想要执行一些操作。 If yes, this combination meets your requirement perfectly.如果是,那么这个组合完全符合您的要求。

myMap.keySet()
    .stream()
    .filter(k -> myMap.get(k) != null && myList.contains(k))
    .findAny()
    .ifPresent(
        // Atleast one not null value is present in myMap with key in myList
        System.out::println // A sample action
    );

Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM