常见的Map集合有哪些?
常用实现类HashMap<K,V>:无序。底层是哈希表
常用实现类LinkedHashMap<K,V>:有序。底层是哈希表+链表
常用实现类TreeMap<K,V>:可排序,底层是红黑树
常用实现类Hashtable<K,V>:功能和HashMap一致,K,V不能是null值
谈谈对HashMap的理解?
HashMap是Java中一种常用的数据结构,它基于哈希表实现。哈希表是一种根据键值对进行快速查找的数据结构,它的特点是可以在常数时间内进行插入、删除和查找操作。HashMap使用键值对的方式存储数据,其中键是唯一的,而值可以重复。
HashMap的内部实现是一个数组,数组中的每个元素称为桶(bucket),每个桶中存放着一个链表或红黑树。当添加一个键值对时,首先计算键的哈希值,然后根据哈希值确定在数组中的位置。如果该位置没有元素,则直接添加到该位置;如果该位置已经存在元素,则将其添加到链表或红黑树的下一个位置。这样,相同哈希值的键值对会放在同一个位置上,但是通过链表或红黑树的方式可以解决哈希冲突的问题。
使用HashMap可以快速地根据键来获取值,具有很高的查找效率。同时,HashMap还可以动态地调整内部数组的大小,以保证装填因子在一个合适的范围内。在使用HashMap时,需要注意键的唯一性,对于复合类型的键,需要实现equals()和hashCode()方法。
总的来说,HashMap是一种高效的查找和存储数据的数据结构,适用于需要快速查找和添加元素的场景。但是在使用过程中需要注意键的唯一性和哈希冲突的问题。
HashMap执行put()方法的过程?
HashMap的put()方法用于将指定的键值对插入到HashMap中。
- 首先,put()方法将键值对中的键通过hash()方法计算出其对应的哈希值。
- 然后,将该哈希值通过hashCode()方法进一步计算得到一个在HashMap内部数组(即哈希表)中的索引位置。
- 如果该索引位置上没有其他键值对存在,那么直接将新的键值对插入到该位置即可。
- 否则,如果该索引位置上已经存在其他键值对,那么需要进行链表的处理。
- 首先,遍历链表,检查是否有与新键值对的键相同的键值对存在。如果有,则用新的值替换旧值,并返回旧值。
- 如果没有与新键值对的键相同的键值对,那么将新的键值对添加到链表的末尾。
- 如果链表的长度超过了HashMap的阈值(默认为8),那么需要将链表转换为红黑树,以提高插入和查找的性能。
- 在插入完成后,如果插入操作会导致HashMap的大小超出负载因子(默认为0.75)乘以当前数组大小的阈值,那么就需要进行rehash操作,即创建一个新的更大的数组,并将旧数组中的键值对重新插入到新数组中。
需要注意的是,HashMap中的键是唯一的,因此如果插入的键已经存在,那么旧值将被新值所替换,并且put()方法会返回旧值。如果插入的键不存在,那么put()方法会返回null。
HashMap中元素如何计算存储位置?
HashMap中元素的存储位置是根据元素的哈希码(hash code)计算得出的。在Java中,所有对象都有一个默认的hashCode()方法,返回一个int类型的哈希码。
HashMap使用哈希码来确定元素在哈希表中的存储位置。在将元素存储到HashMap中时,首先会计算元素的哈希码,然后使用一个哈希函数将哈希码映射到哈希表的一个桶(bucket)中。桶是HashMap中存储元素的基本单位,每个桶可以存储多个元素。
当需要查找HashMap中的元素时,也需要先计算元素的哈希码,然后通过哈希函数找到存储该哈希码的桶,然后在桶中查找元素。
由于哈希码可能存在冲突(即不同元素的哈希码相同),HashMap使用链表或红黑树来解决冲突。当多个元素的哈希码映射到同一个桶时,它们会以链表或红黑树的形式存储在桶中。在查找元素时,会遍历桶中的链表或红黑树来找到目标元素。
通过使用哈希码来确定元素的存储位置,HashMap可以提高元素的查找效率,但也会增加冲突的概率。为了解决冲突,HashMap会动态调整哈希表的大小,以保持桶的平均填充因子在一个合理的范围内。
HashMap中影响性能的两个参数?
在HashMap中,影响性能的两个参数是初始容量(initial capacity)和负载因子(load factor)。
-
初始容量:HashMap在创建时会分配一定的数组空间作为存储桶(bucket)的容器。初始容量的设置会影响HashMap的性能。如果初始容量设置得太小,会导致频繁的扩容操作,增加了操作的时间复杂度。而如果初始容量设置得太大,会浪费内存。因此,合理地选择初始容量可以提高HashMap的性能。
-
负载因子:负载因子是HashMap在自动扩容时的一个触发条件。当HashMap中的元素数量超过负载因子与当前容量的乘积时,HashMap会自动扩容。负载因子的默认值是0.75。负载因子的设置也会影响HashMap的性能。较小的负载因子可以减少冲突的可能性,但会增加内存的开销;较大的负载因子可以减少内存的开销,但会增加冲突的可能性。因此,选择合适的负载因子可以提高HashMap的性能。
综上所述,合理地选择初始容量和负载因子可以提高HashMap的性能。
HashMap什么情况下扩容?如何扩容?
什么情况下会扩容:
a. 当同一索引值下元素个数>8 && 数组长度<64
b. 当数组的格子的占有率达到了0.75的时候会扩容。
扩容方式:新容量 = 旧容量*2;//newCap = oldCap << 1