说我有一个HashMap:
var h = new HashMap();
我的问题是:
h.size() == h.entrySet().size()
总是吗? (假设没有并发问题。)
答案 0 :(得分:3)
假设修改HashMap
和表达式时没有并发问题
h.size() == h.entrySet().size()
将为true
。从HashMap
的{{3}}中,方法size()
:
public int size() {
return size;
}
其中size
是HashMap
声明的实例变量。
调用entrySet()
时,它返回一个名为EntrySet
的嵌套类的实例,其size()
方法是:
public final int size() { return size; }
请注意,EntrySet
不会声明自己的size
变量;从size
返回HashMap
。
还请注意,keySet()
和values()
类似地返回它们自己的嵌套类,这些嵌套类实际上是相同定义的。
因此,无论您在何处调用size()
,它都应返回相同的值,假定在调用之间不会受到其他线程或其他结构修改的干扰。
答案 1 :(得分:2)
source code提示是...
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;
}
请注意,source code会(有点讽刺意味)将您烧死;由于对此类的任何修改都会使大小的状态处于变化之中,因此该假设可能不成立。即使这是一个线程安全的集合,例如,依靠size()
进行任何类型的逻辑控制(例如对HashMap
进行逻辑控制)也是不安全的。
答案 2 :(得分:1)
是的,总是如此,因为哈希图只是条目列表。区别在于所表示的形式,但是大小相同。 (此答案基于不修改HashMap类)