HashMap和HashTable的区别(面试题)
在面试的时候,面试官问到了平时常用的容器HashMap。问到的问题是,请你说说HashMap和HashTable的区别。感觉自己回答得很笼统,比较混乱,现在总结一下:1、是否线程安全HashMap不是线程安全的,HashTable是线程安全的;【HashTable内部的方法基本都使用了synchronized关键字修饰】注意:现在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 没有这样的机制。
点击阅读全文
更多推荐
所有评论(0)