数据结构-5-哈希表

五、哈希表

1、概念

哈希表是一种存在映射关系的数据结构,即给定一个KEY,可以找到对应的VALUE,KEY和VALUE组成了一个Entry(或Node)

KEY是唯一的。如果后添加的Entry和之前的某个Entry的KEY相等,则只会将新的VALUE覆盖旧的VALUE,而不会创建新的Entry

为了维护所有的Entry,可以使用数组结构,同时为了少占用连续的内存空间,可以将相同 hashCode 值的KEY所对应的Entry,使用单向链表结构维护起来(为了更好地提升性能,还可以将满足条件的单向链表转换为二叉树,或将二叉树还原成为单向链表)

2、常用方法

  1. put 添加元素到哈希表中(注意相等的KEY的Entry,其新的VALUE会覆盖旧的VALUE)
  2. get 根据给定的KEY,找到对应的VALUE
  3. remove 根据给定的KEY,移除对应的Entry

3、示例

class HashTable<K, V> {
    
    
    private Entry<K, V>[] table;
    private final int length;
    private int size;

    public HashTable(int length) {
    
    
        this.length = length;
        this.size = 0;
    }

    public void put(K key, V value) {
    
    
        if (null == key || null == value) {
    
    
            throw new NullPointerException();
        }

        if (null == table) {
    
    
            @SuppressWarnings("unchecked")
            Entry<K, V>[] table = (Entry<K, V>[])new Entry[this.length];
            this.table = table;
        }

        int hash = hash(key);
        Entry<K, V> entry = table[hash];
        while (null != entry) {
    
    
            if (entry.key.equals(key)) {
    
    
                entry.value = value;
                return;
            }
            entry = entry.prev;
        }

        entry = table[hash];
        Entry<K, V> put = new Entry<K, V>(key, value);
        table[hash] = put;
        put.prev = entry;

        this.size++;
    }

    public V get(K key) {
    
    
        if (null == key) {
    
    
            throw new NullPointerException();
        }

        int hash = hash(key);
        Entry<K, V> entry = table[hash];
        while (null != entry) {
    
    
            if (entry.key.equals(key)) {
    
    
                return entry.value;
            }
            entry = entry.prev;
        }

        return null;
    }

    public boolean remove(K key) {
    
    
        if (null == key) {
    
    
            throw new NullPointerException();
        }

        int hash = hash(key);
        Entry<K, V> entry = table[hash];
        boolean first = true;
        Entry<K, V> next = table[hash];
        while (null != entry) {
    
    
            if (entry.key.equals(key)) {
    
    
                if (first) {
    
    
                    table[hash] = entry.prev;
                } else {
    
    
                    next.prev = entry.prev;
                }

                this.size--;
                return true;
            }

            entry = entry.prev;
            if (first) {
    
    
                first = false;
            } else {
    
    
                next = next.prev;
            }
        }

        return false;
    }

    public int size() {
    
    
        return this.size;
    }

    private int hash(K key) {
    
    
        return key.hashCode() % this.length;
    }

    private static class Entry<K, V> {
    
    
        private final K key;
        private V value;
        private Entry<K, V> prev;

        private Entry(K key, V value) {
    
    
            this.key = key;
            this.value = value;
        }

        @Override
        public String toString() {
    
    
            return this.key + "=" + this.value;
        }
    }

    @Override
    public String toString() {
    
    
        if (null == table) {
    
    
            return "{}";
        }

        StringBuilder sBuilder = new StringBuilder("{");
        for (int i = 0; i < this.length; i++) {
    
    
            Entry<K, V> entry = table[i];
            while (null != entry) {
    
    
                sBuilder.append(entry.toString()).append(',').append(' ');
                entry = entry.prev;
            }
        }

        return sBuilder.substring(0, sBuilder.length() - 2) + '}';
    }

}

猜你喜欢

转载自blog.csdn.net/adsl624153/article/details/103866147