Java 如果所有元素都以相同的折弯结束,为什么要进行调整大小?

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++) {

我编写了以下代码来测试所有元素在同一个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++) {
        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。为什么?