HashMap和HashTable的区别(面试题)

在面试的时候,面试官问到了平时常用的容器HashMap。问到的问题是,请你说说HashMap和HashTable的区别。

感觉自己回答得很笼统,比较混乱,现在总结一下:

 

1、是否线程安全

  • HashMap不是线程安全的,HashTable是线程安全的;【HashTable内部的方法基本都使用了synchronized关键字修饰】
  • 注意:现在HashTable在我们的开发中很少很少使用。如果你要保证线程安全,推荐使用ConcurrentHashMap

2、效率

  • 因为线程安全的问题,HashMap要比HashTable的效率高一点。

3、对于Null Key和Null Value的支持

  • HashMap中,null可以作为key,但是这样的key只能有一个;可以有一个或者多个键对应的value为null;
  • HashTable中不支持key为null,如果put使用null,那么就会抛出NullPointerException异常;

4、初始容量和每次扩充容量的大小不同

  • HashMap创建的时候如果不指定容量大小,初始容量大小为16,之后每次扩充,容量变为原来的2倍;
  • HashTable创建的时候如果不指定容量大小,初始容量大小为11,之后每次扩充,容量会变为2n + 1;
  • HashMap创建的时候给定初始容量大小,HashMap 会将其扩充为2的幂次方大小(HashMap 中的tableSizeFor()方法保证,下面给出了源代码)。也就是说 HashMap 总是使用2的幂作为哈希表的大小,后面会介绍到为什么是2的幂次方。
  • HashMap 中带有初始容量的构造函数:
  •     public HashMap(int initialCapacity, float loadFactor) {
            if (initialCapacity < 0)
                throw new IllegalArgumentException("Illegal initial capacity: " +
                                                   initialCapacity);
            if (initialCapacity > MAXIMUM_CAPACITY)
                initialCapacity = MAXIMUM_CAPACITY;
            if (loadFactor <= 0 || Float.isNaN(loadFactor))
                throw new IllegalArgumentException("Illegal load factor: " +
                                                   loadFactor);
            this.loadFactor = loadFactor;
            this.threshold = tableSizeFor(initialCapacity);
        }
         public HashMap(int initialCapacity) {
            this(initialCapacity, DEFAULT_LOAD_FACTOR);
        }
  • 下面这个方法保证了 HashMap 总是使用2的幂作为哈希表的大小。
  •     /**
         * Returns a power of two size for the given target capacity.
         */
        static final int tableSizeFor(int cap) {
            int n = cap - 1;
            n |= n >>> 1;
            n |= n >>> 2;
            n |= n >>> 4;
            n |= n >>> 8;
            n |= n >>> 16;
            return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
        }
  • HashTable创建时如果给定了容量初始值,那么 Hashtable 会直接使用你给定的大小

5、底层数据结构

  •  JDK1.8 以后的 HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为8)时,将链表转化为红黑树,以减少搜索时间;
  • Hashtable 没有这样的机制。
  • 30
    点赞
  • 201
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值