HashMap和HashTable区别对比

这里先说说HashSet。

  • HashSet内部也是使用的HashMap来存储
    在去重的时候使用很方便
// 得到列表
        List<String> list = getList();
        // 去重
        HashSet h = new HashSet(list);
        list.clear();
        list.addAll(h);//最后得到的就是没有重复数据的list
HashMap和HashTable
  • HashMap和HashTable几乎等价
    • HashMap效率高,因为它不是线程安全的,而HashTable是线程安全的。
    • HashMap可以存储null的key值,HashTable不行
    • 迭代算法不同HashMap是使用fail-fast,所以在有其他线程更改了结构会抛出异常。
    • HashTable是线程安全的,所以在单线程操作中效率比HashMap慢,所以那种情况下,使用HashMap更好
    • HashMap不能保证元素次序是一直不变的(在添加过程中,超过容积,会像Arraylist那样增加到原有的两倍,然后会倒序的方式装进去,顺序就改变了)

我们主要关注两个的get 和put 方法。

  • HashMap
@Override public V put(K key, V value) {
        if (key == null) {//这就看到可以key为null
            return putValueForNullKey(value);
        }

        int hash = Collections.secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        int index = hash & (tab.length - 1);
        for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) {
            if (e.hash == hash && key.equals(e.key)) {//该key已存在则更新值
                preModify(e);
                V oldValue = e.value;
                e.value = value;
                return oldValue;
            }
        }

        // No entry for (non-null) key is present; create one
        modCount++;
        if (size++ > threshold) {//检测大小是否超出容量
            tab = doubleCapacity();//重新修改
            index = hash & (tab.length - 1);
        }
        addNewEntry(key, value, hash, index);//新添加
        return null;
    }

public V get(Object key) {
        if (key == null) {//如果key为null,在存null中找
            HashMapEntry<K, V> e = entryForNullKey;
            return e == null ? null : e.value;
        }

        int hash = Collections.secondaryHash(key);
        HashMapEntry<K, V>[] tab = table;
        for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)];
                e != null; e = e.next) {//链表方式,一个一个往下找
            K eKey = e.key;
            if (eKey == key || (e.hash == hash && key.equals(eKey))) {//如果当前缓存区的key和传入key相同,那么就直接取值。或者hash相同的时候,则比较key值
                return e.value;
            }
        }
        return null;
    }
  • HashTable
public synchronized V put(K key, V value) {
        if (key == null) {//这里就能看出hashtable是不允许存空的key和value的
            throw new NullPointerException("key == null");
        } else if (value == null) {
            throw new NullPointerException("value == null");
        }
        //后面和HashMap没太大区别,所以省略
    }

    public synchronized V get(Object key) {
        //get也是和HashMap查不多的。
    }

可以很明显的看到,HashTable的put和get方法都加入了synchronized,保证同一时间只能有个线程来操作,所以在单线程的时候,HashTable也确实效率要低一点。
关于HashMap也可以使用这种方式来同步:Collections.synchronizedMap(hashMap);

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值