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

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;
        }
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值