Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
2016-12-12 23:00
579 查看
2017年的秋招彻底结束了,感觉Java上面的最常见的集合相关的问题就是hash……系列和一些常用并发集合和队列,堆等结合算法一起考察,不完全统计,本人经历:先后百度、唯品会、58同城、新浪微博、趣分期、美团点评等都在1、2……面的时候被问过无数次,都问吐了&_&,其他公司笔试的时候,但凡有Java的题,都有集合相关考点,尤其hash表……现在总结下。
2016-12-15 更新:Java 8 对 HashMap 的改进
2016-12-12 整理jdk 1.8之前的HashMap实现
2016-12-15 更新:Java 8 对 HashMap 的改进
如果说Java的hashmap是数组+链表,那么JDK 8之后就是数组+链表+红黑树组成了hashmap。之前的实现机制和原理在下面12-12期整理过,这次只说下新加的红黑树机制。
在之前谈过,如果hash算法不好,会使得hash表蜕化为顺序查找,即使负载因子和hash算法优化再多,也无法避免出现链表过长的情景(这个概论虽然很低),于是在JDK1.8中,对hashmap做了优化,引入红黑树。具体原理就是当hash表中每个桶附带的链表长度默认超过8时,链表就转换为红黑树结构,提高HashMap的性能,因为红黑树的增删改是O(logn),而不是O(n)。
红黑树的具体原理和实现以后再总结。
View Code
从源码中看出 synchronizedMap()方法返回一个SynchronizedMap类的对象,而在SynchronizedMap类中使用了synchronized来保证对Map的操作是线程安全的,故效率其实也不高。
临时小结:感觉针对Java的hashmap和hashtable面试,或者理解,到这里就可以了,具体就是多写代码实践。
2016-12-15 更新:Java 8 对 HashMap 的改进
2016-12-12 整理jdk 1.8之前的HashMap实现
2016-12-15 更新:Java 8 对 HashMap 的改进
如果说Java的hashmap是数组+链表,那么JDK 8之后就是数组+链表+红黑树组成了hashmap。之前的实现机制和原理在下面12-12期整理过,这次只说下新加的红黑树机制。
在之前谈过,如果hash算法不好,会使得hash表蜕化为顺序查找,即使负载因子和hash算法优化再多,也无法避免出现链表过长的情景(这个概论虽然很低),于是在JDK1.8中,对hashmap做了优化,引入红黑树。具体原理就是当hash表中每个桶附带的链表长度默认超过8时,链表就转换为红黑树结构,提高HashMap的性能,因为红黑树的增删改是O(logn),而不是O(n)。
红黑树的具体原理和实现以后再总结。
主要看put方法实现
// synchronizedMap方法 public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) { return new SynchronizedMap<>(m); } // SynchronizedMap类 private static class SynchronizedMap<K,V> implements Map<K,V>, Serializable { private static final long serialVersionUID = 1978198479659022715L; private final Map<K,V> m; // Backing Map final Object mutex; // Object on which to synchronize SynchronizedMap(Map<K,V> m) { this.m = Objects.requireNonNull(m); mutex = this; } SynchronizedMap(Map<K,V> m, Object mutex) { this.m = m; this.mutex = mutex; } public int size() { synchronized (mutex) {return m.size();} } public boolean isEmpty() { synchronized (mutex) {return m.isEmpty();} } public boolean containsKey(Object key) { synchronized (mutex) {return m.containsKey(key);} } public boolean containsValue(Object value) { synchronized (mutex) {return m.containsValue(value);} } public V get(Object key) { synchronized (mutex) {return m.get(key);} } public V put(K key, V value) { synchronized (mutex) {return m.put(key, value);} } public V remove(Object key) { synchronized (mutex) {return m.remove(key);} } // 省略其他方法 }
View Code
从源码中看出 synchronizedMap()方法返回一个SynchronizedMap类的对象,而在SynchronizedMap类中使用了synchronized来保证对Map的操作是线程安全的,故效率其实也不高。
为什么HashTable的默认大小和HashMap不一样?
前面分析了,Hashtable 的扩容方法是乘2再+1,不是简单的乘2,故hashtable保证了容量永远是奇数,结合之前分析hashmap的重算hash值的逻辑,就明白了,因为在数据分布在等差数据集合(如偶数)上时,如果公差与桶容量有公约数 n,则至少有(n-1)/n 数量的桶是利用不到的,故之前的hashmap 会在取模(使用位与运算代替)哈希前先做一次哈希运算,调整hash值。这里hashtable比较古老,直接使用了除留余数法,那么就需要设置容量起码不是偶数(除(近似)质数求余的分散效果好)。而JDK开发者选了11。JDK 8对HashMap有了什么改进?说说你对红黑树的理解?
参考更新的jdk 8对hashmap的的改进部分整理,并且还能引申出高级数据结构——红黑树,这又能引出很多问题……学无止境啊!临时小结:感觉针对Java的hashmap和hashtable面试,或者理解,到这里就可以了,具体就是多写代码实践。
相关文章推荐
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
- Java集合专题总结(1):HashMap 和 HashTable 源码学习和面试总结
- Java集合源码学习笔记(五)ArrayList,LinkedList,Vector和Hashtable,HashMap的比较
- 集合源码学习(十):HashTable(Java8)与HashMap比较
- HashMap 和 HashTable 源码学习和面试总结
- Java集合--Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
- Java集合学习--HashMap、LinkedHashMap、TreeMap、HashTable
- 集合源码学习(七):HashMap(Java8)
- JAVA学习18_Java集合---HashMap源码剖析
- Java集合源码学习(20)_Map接口的实现HashMap
- Java集合源码学习(24)_ConcurrentMap的实现类ConcurrentHashMap
- Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
- Java 8集合框架源码学习——HashMap
- 【Java集合学习系列】HashMap实现原理及源码分析
- 哈希算法-----JAVA 源码中实现的HashMap学习总结
- Java 集合系列之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
- Java集合深入学习总结-HashMap
- Java 集合系列14之 Map总结(HashMap, Hashtable, TreeMap, WeakHashMap等使用场景)
- Java集合源码学习笔记(四)HashMap分析
- java集合: List、Set、Map总结 + HashMap/Hashtable 差别