Java 如果所有元素都以相同的折弯结束,为什么要进行调整大小?
我编写了以下代码来测试所有元素在同一个bucket中结束时hashmap的行为:-Java 如果所有元素都以相同的折弯结束,为什么要进行调整大小?,java,reflection,hashmap,hashtable,Java,Reflection,Hashmap,Hashtable,我编写了以下代码来测试所有元素在同一个bucket中结束时hashmap的行为:- public class DerivedMain { int data = 10; @Override public int hashCode() { return data; } public static void main(String[] args) { HashMap m = new HashMap(); for(int i=0;i<20;i++) {
public class DerivedMain {
int data = 10;
@Override
public int hashCode() {
return data;
}
public static void main(String[] args) {
HashMap m = new HashMap();
for(int i=0;i<20;i++) {
m.put(i, i);
}
Field tableField = null;
try {
tableField = HashMap.class.getDeclaredField("table");
} catch (NoSuchFieldException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tableField.setAccessible(true);
Object[] table = null;
try {
table = (Object[]) tableField.get(m);
} catch (IllegalArgumentException | IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(table == null ? 0 : table.length);
}
公共类DerivedMain{
int数据=10;
@凌驾
公共int hashCode(){
返回数据;
}
公共静态void main(字符串[]args){
HashMap m=新的HashMap();
对于(int i=0;i,因为a就是这样工作的:
当哈希表中的条目数超过加载因子与当前容量的乘积时,哈希表将重新刷新
HashMap只知道,一旦达到限制,冲突的概率就会变得太高,它必须重新刷新以降低该概率,并为将来的条目留出空间。它假设hashCode的实现是好的,并且绝对无法知道冲突是否是由坏的实现造成的hashCode的一部分。因为a就是这样工作的:
当哈希表中的条目数超过加载因子与当前容量的乘积时,哈希表将重新刷新
HashMap只知道,一旦达到限制,冲突的概率就会变得太高,它必须重新刷新以降低该概率,并为将来的条目留出空间。它假设hashCode的实现是好的,并且绝对无法知道冲突是否是由坏的实现造成的您可以调试代码,然后您会发现类“DerivedMain”中定义的“hashCode”方法将永远不会被调用,因此所有元素都不在同一个bucket中。但输出为32的真正原因是hashmap的大小(20)大于阈值(table.size*loadfactor)。如果你想知道hashmap的更多工作细节,你应该阅读jdk中的源代码。你可以调试你的代码,然后你会发现在你的类“DerivedMain”中定义的“hashcode”方法将永远不会被调用,因此所有元素都不在同一个bucket中。但是输出为32的真正原因是大小(20)hashmap的值大于阈值(table.size*loadfactor)。如果您想了解hashmap的更多工作细节,应该阅读jdk中的源代码。如果我重写了DerivedMain类中的hashcode方法,为什么永远不会调用该方法?您将Integer
s作为键放在映射中。因此Integer#hashcode()
将被调用。您没有覆盖它(您也不能)。您可以将DerivedMain
实例放在映射中,然后使用您的hashcode(但您还需要提供一个equals
).好的…谢谢,现在我正在修改我在main类中的实现,不再创建整数作为键,现在我将创建为:-DerivedMain d=new DerivedMain();m.put(d,i);现在我得到的hashmap容量为64。为什么?如果我重写了DerivedMain类中的hashcode方法,为什么永远不会调用该方法?您将Integer
s作为映射中的键。因此将调用Integer#hashcode()
。您没有重写该方法(您也不能)。您可以将DerivedMain
实例放在映射中,然后使用hashcode(但您还需要提供一个equals
)。好的……谢谢,现在我正在更改main类中的实现,在这里我将创建为:-DerivedMain d=new DerivedMain();m.put(d,i);现在我得到的hashmap容量为64。为什么?