HashMap的原理
HashMap的结构如图所示:
Map里面保存的是key-value键值对,键值对是以LinkedList的结构保存在Bucket中,HashMap的key和value值可以为null。
HashMap的工作原理
HashMap保存对象用put(K key, V value),获取某对象用get(K key)。当我们保存对象是首先对Key调用hashCode方法,返回的值作为Bucket的位置,讲键值对保存到Bucket之中。获取对象时,我们同样先对key调用hashcode方法,查找到Bucket的位置,从而返回value的值。
若两个对象是否可以产生相同的hashcode?
两个对象可以产生相同的hashcode,由于HashMap是根据Bucket存储的,Bucket中的数据结构是LinkedList,故,若两对象hashcode相同则会依次存放在LinkedList中,当查找对象的时候根据hashCode进行查找找到相应的Bucket,然后依次在LinkedList中查找对象,若key只与查找的key值相同(equals)则找到该对象。
若HashMap的大小超过其负载因子的容量怎么办?
若超过其敷在引资的容量则将会创建一个以前大小两倍的HashMap,然后将entity通过运算hashcode的方式重新保存到新的HashMap之中。
!!但是,由于Bucket中的对象是以LinkedList进行保存的,所以在新的HashMap中,两处于同一个Bucket中的对象的顺序会发生反转(LinkedList链表,查询从头查询,插入式从链表头插入),那么问题就来了,若有两个线程同时操作此HashMap,若第一个线程刚好已经完成扩展HashMap的操作,而第二个线程刚好开始扩展HashMap,这个时候就会出现,已经扩展的HashMap作为原始数据,被第二个线程扩展(因此可以看到HashMap并非线程安全的)。
HashTable与HashMap的区别
HashTable几乎可以等价HashMap,HashTable是JDK1.0的java特性,它是线程安全的,而HashMap并非线程安全的,HashTable支持序列化,因此在单线程的环境下HashTable相比HashMap效率要第。HashTable不支持key和value为空,而HashMap没有这个限制。