Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在put方法中重新散列哈希映射_Java_Hashmap_Out Of Memory - Fatal编程技术网

Java 在put方法中重新散列哈希映射

Java 在put方法中重新散列哈希映射,java,hashmap,out-of-memory,Java,Hashmap,Out Of Memory,我试图在Java中实现一个单独的链接哈希映射。在put()-方法中,如果加载因子(元素数/数组大小)变大,我想重新散列映射。为此,我编写了另一个方法rehash(),它通过将数组/容量的大小加倍,然后再次添加所有条目(至少我希望它这样做)来重新显示列表。问题是,当我测试它时,我得到了一个“java.lang.OutOfMemoryError:java堆空间”,我猜这是因为我在rehash()方法中调用了put()方法。问题是我真的不知道如何解决这个问题。我想知道是否有人可以检查我的代码,给我反馈

我试图在Java中实现一个单独的链接哈希映射。在put()-方法中,如果加载因子(元素数/数组大小)变大,我想重新散列映射。为此,我编写了另一个方法rehash(),它通过将数组/容量的大小加倍,然后再次添加所有条目(至少我希望它这样做)来重新显示列表。问题是,当我测试它时,我得到了一个“java.lang.OutOfMemoryError:java堆空间”,我猜这是因为我在rehash()方法中调用了put()方法。问题是我真的不知道如何解决这个问题。我想知道是否有人可以检查我的代码,给我反馈或给我一个如何继续的提示。 下面代码中的条目是哈希映射类中的嵌套私有类

提前谢谢

put()方法:


其中size()返回映射中(键、值)对的数量,capacity是数组表(存储链接列表的位置)的大小。

您已经添加了
rehash()
,但是仍然缺少
load()
实现(或者在load内部,添加
size()

不过,模式看起来很清晰,允许猜测,等待更多信息

您告诉我们,当荷载系数达到
放置
内的某个点时,您将重新进行灰化。这将使内部数组加倍,并再次调用put。最后你没有了记忆

其中,我打赌在你放置的地方会发生一些微妙的或不太微妙的递归,它通过加倍内存使用来重新放置,然后重新放置,这以某种方式创建了一个
rehash
ing

第一种可能性是,有一些跟踪数组状态的内部变量未正确重置(例如,占用的条目数…)。将“旧”阵列数据与正在构建的新阵列数据混淆可能是罪魁祸首


另一种可能性是您的
put
实现,但它需要一步一步地调试—我建议您执行调试。

一旦您重新刷新映射,一切都将不一样。入口设置的桶等。 所以

  • 创建临时表
  • 通常使用当前的get方法获取值
  • 然后根据重新灰化到新的桶大小创建新的桶,并将新容量添加到表中。(不要使用PUT)
  • 然后用刚创建的表替换现有表。确保与新表大小相关的所有值也已更改,例如基于threhholds、capcity等的桶选择方法

最后,使用打印语句跟踪新存储桶和存储桶之间的项目移动。

什么是
load()
?抱歉,我编辑了它!是的,但是size()是如何实现的
nr_of_keys
?是的,size()只返回nr_of_keys属性!旁注:在我看来,
do while()
可以在put中为您节省几行
public V put(K key,V value) {
    int idx = key.hashCode()%capacity;  //Calculate index based on hash code.
    if(idx<0) {    
        idx+=this.capacity;  //if index is less than 0 add the length of the array table
    }
    if(table[idx]==null) {   //If list at idx is empty just add the Entry-node
        table[idx] = new Entry<K,V>(key,value);
        nr_of_keys +=1;
        if(this.load()>=this.load_factor) {  //Check if load-factor is greater than maximum load. If this is the case rehash.
            rehash();
        }
        return null;
    } else {
        Entry<K,V> p = table[idx];  //dummy pointer
        while(p.next!=null) { //while next node isn't null move the pointer forward
            if(p.getKey().equals(key)) {    //if key matches:
                if(!p.getValue().equals(value)) { //if value don't match replace the old value.
                    V oldVal = p.getValue();
                    p.setValue(value);
                    return oldVal; 
                }
            } else {
                p=p.next;
            }
        }
        if(p.getKey().equals(key)) {   //if the key of the last node matches the given key:
            if(!p.getValue().equals(value)) {
                V oldVal = p.getValue();
                p.setValue(value);
                return oldVal;
            } else {
                return null;
            }
        }
        p.next = new Entry<K,V>(key,value); //key doesn't exist so add (key,value) at the end of the list.
        nr_of_keys +=1;
        if(this.load()>=this.load_factor) { //if load is to large rehash()
            rehash();
        }
        return null;
    }
    
}
public void rehash() {
    Entry<K,V>[] tmp = table;  //create temporary table
    int old_capacity = this.capacity;  //store old capacity/length of array.
    this.capacity = 2*capacity; //New capacity is twice as large
    this.nr_of_keys=0; //reset nr. of keys to zero.
    table = (Entry<K, V>[]) new Entry[capacity];  //make this.table twice as large
    for(int i=0; i<old_capacity;i++) { //go through the array
        Entry<K,V> p = tmp[i]; //points to first element of list at position i.
        while(p!=null) {
            put(p.getKey(), p.getValue());
            p=p.next;
        }
    }
}
public double load() {
    return((double) this.size())/((double)this.capacity);
}