Is map.size() always the same as map.entrySet().size()



说我有一个hashmap:

var h = new HashMap();

我的问题是:

h.size() == h.entrySet().size()

总是吗?(假设没有并发问题)。

假设没有并发问题修改HashMap,则您的表达式

h.size() == h.entrySet().size()

将是true。从HashMap的源代码,方法size()

public int size() {
    return size;
}

其中 size是由 HashMap声明的实例变量。

调用entrySet()时,它返回一个名为EntrySet的嵌套类的实例,其size()方法为:

public final int size()                 { return size; }

请注意,EntrySet不会声明其自己的size变量;它从HashMap返回size

还请注意,keySet()values()同样返回自己的嵌套类,这些类实际上相同定义。

因此,无论您在何处呼叫size(),都应该相同返回,假设呼叫之间没有其他线程或其他结构修改的干扰。

源代码表明它是...

final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
    public final int size() {
        return size;
    }
    // rest of code
}

...我的反编译器也建议。

public final int size() {
    return HashMap.this.size;
}

请注意,您将(具有讽刺意味的是)被ConcurrentHashMap烧毁;由于对此类别的任何修改都会使大小的状态变化,因此该假设可能无法成立。即使这是一个线程安全的集合,也不安全地依靠size()来执行任何形式的逻辑控制,例如使用HashMap

是的,这始终是正确的,因为哈希图只是条目列表。区别在于表示形式,但大小相同。(此答案基于不修改hashmap类)

最新更新