100000 +条目后无效的哈希条目

时间:2015-09-16 01:47:52

标签: java hashmap

我已经使用线性探测实现了HashMap的哈希冲突。

df1.hist(column='Human', by='Re')

它似乎完全按预期工作,除了每100,000个条目左右将返回错误的哈希值。我可以通过这个测试相当可靠地重现它

import java.util.Optional;

@SuppressWarnings("unchecked")
public abstract class HashMap<T, R> {

    private static final int MIN_CAPACITY = 2;
    private Entry<T, R>[] table;
    private int internalSize, size;
    private float fillRatio;

    public HashMap() {
        this(MIN_CAPACITY);
    }

    public HashMap(int initialCapacity) {
        this(initialCapacity, .75f);
    }

    public HashMap(int initialCapacity, float fillRatio) {
        this.table = new Entry[Math.max(MIN_CAPACITY, initialCapacity)];
        this.fillRatio = fillRatio;
    }

    public Optional<R> put(T key, R value) {
        int index = getIndex(key);
        Entry<T, R> current = table[index];
        table[index] = new Entry<>(key, value);

        if(value == null && current != null && current.getValue() != null) {
            size--;
        } else if(value != null && (current == null || current.getValue() == null)){
            size++;
        }

        if(current == null && ++internalSize >= (table.length * fillRatio)) {
            resizeTable();
        }

        if(current != null) {
            return Optional.ofNullable(current.getValue());
        }
        return Optional.empty();
    }

    public Optional<R> get(T key) {
        int index = getIndex(key);
        Entry<T, R> entry = table[index];
        if(entry != null)
            return Optional.ofNullable(entry.getValue());
        return Optional.empty();
    }

    public boolean has(T key) {
        return get(key).isPresent();
    }

    public int getSize() {
        return size;
    }

    protected void resizeTable() {
        internalSize = size = 0;
        Entry<T, R>[] tmp = table;
        table = new Entry[(int) ((table.length /fillRatio)* 2)];
        for(Entry<T, R> entry : tmp){
            if(entry != null) {
                put(entry.getKey(), entry.getValue());
            }
        }
    }

    private int getIndex(T key) {
        int hash = key.hashCode();
        int index = (((hash % table.length) + table.length) % table.length);
        while(table[index] != null && table[index].getKey().hashCode() != hash) {
            if(++index == table.length) {
                index = 0;
            }
        }
        return index;
    }

    public static final class Entry <T, R> {
        private final T key;
        private final R value;

        public Entry(T key, R value) {
            this.key = key;
            this.value = value;
        }

        public T getKey() {
            return key;
        }

        public R getValue() {
            return value;
        }
    }

}

我没有看到我的问题是什么,而且我没有考虑调试这种罕见事件的好方法。对于我可能做错了什么或者如何调试这个而不花钱永远的想法?

1 个答案:

答案 0 :(得分:0)

How does a Java HashMap handle different objects with the same hash code?回答了我的问题。我的HashMap实现不处理具有相同哈希码的不同对象。只有当哈希码对于相同的对象是唯一的时,它才能正常工作。