说我有一个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类)