7

我遇到了一个代码片段,该代码片段使用其条目集迭代地图并仅在 entry != null 时执行一些操作

据我所知,即使我们没有在 map 中输入任何内容,也会map.entrySet返回一个空集而不是null。即使我把{null,null}条目也将是[null=null]一个包含这些元素的实例。但实例不会为空。

Map<String, String> map = new HashMap<String, String>();
        map.put(null, null);
        map.put(string1, string1);
        for(Map.Entry<String, String> entry : map.entrySet()){
            if(entry != null){
                                  //do something
            }

        }

我有以下基本问题:

  1. 在什么情况下 HashMap 中的条目将为 NULL?
  2. 支票是否有效

我坚信if(entry != null)过度谨慎,应该将其删除。我只是想确定一下。

4

4 回答 4

7

迭代器可以为支持空值的集合返回空值,但正如您自己展示的那样,这对于Maps. 检查是多余的和误导性的。

于 2015-05-18T07:02:52.117 回答
4

场景无效。这是来自 hashmap 实现的代码

private Set<Map.Entry<K,V>> entrySet0() {
    Set<Map.Entry<K,V>> es = entrySet;
    return es != null ? es : (entrySet = new EntrySet());
}

所以,你不应该得到一个空值

于 2015-05-18T07:37:56.587 回答
0

检查显然是多余的。@Kayaman 的回答很好。
但是,我不同意您的评论和@bobK 的回答。

我认为您可能会混淆 entry 和 entrySet。检查与方法的imp无关entrySet()。该方法entrySet()只是确保entrySet不为null,而您示例中的判断是确保Set中的entry不为null。

Set 可以包含一个空对象,因此有时我们需要做 NPE 保护。我们这里不需要做检查的原因是 Map Class 确保条目集中的条目不为空。EntrySet 类中的方法forEach()是重要的一个。

    public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
        Node<K,V>[] tab;
        if (action == null)
            throw new NullPointerException();
        if (size > 0 && (tab = table) != null) {
            int mc = modCount;
            for (int i = 0; (i < tab.length && modCount == mc); ++i) {
                for (Node<K,V> e = tab[i]; e != null; e = e.next)
                    //e is not null
                    action.accept(e);
            }
            if (modCount != mc)
                throw new ConcurrentModificationException();
        }
    }

e != null在这里得到保证。

于 2018-09-26T09:09:52.473 回答
-1

检查可能只是检查 Map 是否被实例化以避免NullPointerException进一步引用该对象。
如果您认为这是出于谨慎考虑,最好确保 Map 已在构造函数中实例化

于 2015-05-18T07:14:20.637 回答