【java集合】自己实现简易的Hashtable

来源:互联网 发布:淘宝买电玩人马皮肤 编辑:程序博客网 时间:2024/05/15 05:41

Map接口:

/** * Created by hasee on 2017/11/5. */public interface IMyMap<K, V> {    V put(K key, V value);    V get(K key);    int size();    boolean isEmpty();    interface Entry<K, V>{}}

Hashtable实现:

/** * Hashtable与HashMap的主要区别: * 1.Hashtable是线程安全的 * 2.Hashtable不允许key和value为空 */public class MyHashTable<K, V> implements IMyMap<K, V> {    private int size;    private int threshold;    private float loadFactor;    private Entry<K, V>[] table;    public MyHashTable() {        this(11, 0.75f);    }    public MyHashTable(int initialCapacity) {        this(initialCapacity, 0.75f);    }    public MyHashTable(int initialCapacity, float loadFactor) {        this.loadFactor = loadFactor;        this.table = new Entry[initialCapacity];        this.threshold = (int)(initialCapacity * loadFactor);    }    @Override    public synchronized V put(K key, V value) {        if (null == value)            throw new NullPointerException("不允许value为空");        int hash = hash(key);        int index = indexFor(hash, table.length);        for (Entry<K, V> e=table[index]; e!=null; e=e.next){            if (e.key.equals(key)){                V oldValue = e.value;                e.value = value;                return oldValue;            }        }        this.table[index] = new Entry<K, V>(hash, table[index], key, value);        if (size++ >= threshold)            resize();        return null;    }    @Override    public synchronized V get(K key) {        int hash = hash(key);        int index = indexFor(hash, table.length);        for (Entry<K, V> e=table[index]; e!=null; e=e.next){            if (e.hash == hash && e.key.equals(key)){                return e.value;            }        }        return null;    }    private static final int hash(Object o){        return 0x7FFFFFFF & o.hashCode();    }    private static final int indexFor(int hash, int length){        return hash % length;    }    //扩容    private void resize(){        int oldCapacity = table.length;        int newCapacity = (oldCapacity << 1) + 1;        Entry[] newTable = new Entry[newCapacity];        for (int i=0; i<oldCapacity; i++){            for (Entry<K, V> e=table[i]; e!=null;){                /**                 * 这里有个细节:                 * 需要先复制一个e引用给old,然后才让e指向下一个元素。                 * 如果不这样做的话(即只用一个e引用),e.next = newTable[index];这一步会使原本的链表断开,                 * 那么e之后的元素就无法再引用到了,元素就会因此丢失                 */                Entry<K, V> old = e;                e = e.next;                int index = indexFor(old.hash, newCapacity);                old.next = newTable[index];                newTable[index] = old;            }        }        threshold = (int)(newCapacity * loadFactor);        table = newTable;    }    @Override    public synchronized int size() {        return this.size;    }    @Override    public synchronized boolean isEmpty() {        return this.size == 0;    }    private static class Entry<K, V> implements IMyMap.Entry<K, V>{        int hash;        Entry<K, V> next;        K key;        V value;        public Entry(int hash, Entry<K, V> next, K key, V value) {            this.hash = hash;            this.next = next;            this.key = key;            this.value = value;        }    }}