目标
- 为什么重写Equals还要重写HashCode方法
- HashMap如何避免内存泄漏问题
- HashMap1.7底层是如何实现的
- HashMapKey为null存放在什么位置
- HashMap如何解决Hash冲突问题
- HashMap底层采用单链表还是双链表
- 时间复杂度O(1)、O(N)、O(Logn)区别
- HashMap根据key查询的时间复杂度
- HashMap底层是有序存放的吗?
我们先来说说吧,为什么HashMap会这么重要?博主浅薄的知识感觉,他的重要性主要是在jdk8之后底层代码进行了大更新之后才会特别的火。为什么呢?我们来说说吧。
在jdk8之前,HashMap的底层采用的是数组+链表的形式实现的。而到了jdk8,它的底层变成了数组+链表+红黑树实现 。
就这一个红黑树的实现,让我们使用它的时候,在产生hash冲突的时间复杂度足足从O(n)变成了O(LogN),这个巨大的变化,导致它越来越常用。
1.HashMap与HashTable之间的区别
- HashMap实现不同步,线程不安全。 HashTable线程安全 HashMap中的key-value都是存储在Entry中的。
- Hashtable 继承 Dictionary 类,而 HashMap 继承 AbstractMap
public class Hashtable extends Dictionary implements Map
public class HashMap extends AbstractMap implements Map
- Hashtable中的方法是同步的,而HashMap中的方法在增加同步处理是非同步的。
- Hashtable 中, key 和 value 都不允许出现 null 值。 在 HashMap 中, null 可以作为键,这样的键只有一个。所以在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断
- 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重写了hashCode()方法
2.手写HashMap
手写JDK7的HashMap
手写JDK7的HashMap(暂无)
3.为什么重写equals还要重写hashcode方法
我们在之前手写JDK7的HashMap提到过,为什么不使用自定义类来当做键值,而是使用数字和String类型,在最后的ExtHashMap.java中的put()方法,我们使用了一个for循环进行判断是否存在重复的key值,这个问题,我们可以转换到我们用的Set集合。Set集合是不存在重复数据的,那他是怎么做到不存在重复数据的呢?
HashMap源码分析------HashSet集合实现无重复数据
HashMap如何避免内存泄漏问题
其实,这个问题间接性的解释了怎么解决。
为什么会内存泄露?
因为我们没有重写hashcode()和equals()方法,导致同一对象同一属性值,但不同地址的原因,重复添加对象导致内存溢出(强引用),只要我们将这hashcode()和equals()重写即可解决问题