HashMap(int initialCapacity)指定集合大小
介绍
首先设置一个合理的初始化容量可以提高HashMap的性能 在当我们对HashMap初始化没设置初始化容量时,系统会默认创建一个容量为16的大小的集合。若我们的所需的集合很小则会造成内存浪费,而当HashMap的容量值超过了临界值(threshold)时HashMap将会重新扩容的下一个2的指数幂(16->32)。HashMap扩容将会重新创建hash表降低性能。
方法
官方
- 如果不超过12个键值对,可以不设置
- 如果超出,按initialCapacity = (需要存储的元素个数 / 负载因子) + 1公式计算后设置
- 官方的建议是initailCapacity设置成2的n次幂
其他
如何设置一个合理的初始化容量 当我们使用HashMap(int initialCapacity)来初始化容量的时候,jdk会默认帮我们计算一个相对合理的值当做初始容量。当HashMap的容量值超过了临界值(threshold)时就会扩容,threshold = HashMap的容量值0.75,比如初始化容量为8的HashMap当大小达到80.75=6时将会扩容到16。当我们设置HashMap的初始化容量是遵循expectedSize /0.75+1,比如expectedSize是6时 6/0.75+1=9,此时jdk处理后会被设置成16,大大降低了HashMap被扩容的几率。
当我们通过HashMap(int initialCapacity)设置初始容量的时候,HashMap并不一定会直接采用我们传入的数值,而是经过计算,得到一个新值,目的是提高hash的效率。(1->2、3->4、7->8、9->16)
HashMap会选择大于初始化值的第一个2的幂作为容量。不然会限制了散列的范围。 HashMap 之所以速度快,因为它使用的是散列表,根据 key 的 hashcode 值生成数组下标(通过内存地址直接查找,没有任何判断),时间复杂度完美情况下可以达到 n1(和数组相同,但是比数组用着爽多了,但是需要多出很多内存,相当于以空间换时间)。
集合介绍
List Set Map 都是接口 List Set继承Collection(Collections是工具类)
List子类(有序,可重复)—ArrayList、Vector、LinkedList
ArrayList、Vector 底层是数组(查找快,增删慢) 前者线程不安全,后者线程安全
Linkedlist 底层是链表查找慢,增删快
Set(无序,唯一)—HashSet TreeSet LinkedHashSet
HashSet 底层是哈希表(hashcode equals)
LinkedHashSet 底层是链表和哈希表–插入有序唯一,链表保证有序、哈希表保证唯一
TreeSet 底层结构是红黑树–唯一有序,自然排序、比较器排序
Map HashMap ThreeMap HashTable
HashMap HashTable 无序 前者非线程安全,效率高,允许有null(kv),后者线程安全,效率低,不允许null值。
TreeMap 有序
在集合中常见的数据结构(掌握) ArrayXxx:底层数据结构是数组,查询快,增删慢 LinkedXxx:底层数据结构是链表,查询慢,增删快 HashXxx:底层数据结构是哈希表。依赖两个方法:hashCode()和equals() TreeXxx:底层数据结构是二叉树。两种方式排序:自然排序和比较器排序 <部分整理别人知识点>