你好,我是吴计可师,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。
在 Java 中,List 和 Map 的扩容是非常重要的概念,因为它直接影响性能,特别是在处理大量数据时。下面详细介绍几种常见的 List 和 Map 的扩容方式以及它们的扩容因子。
ArrayList 是一个基于数组实现的动态数组。当你向 ArrayList 中添加元素并且容量不足时,ArrayList 会自动扩容。扩容的方式如下:
初始容量:默认情况下,ArrayList 的初始容量是 10。
扩容因子:ArrayList 在扩容时,会将容量增加为原容量的 1.5 倍(即原容量的 150%)。
假设 ArrayList 当前的容量是 n,当需要添加元素时,如果容量不够,它会扩容为 n + n / 2,即 1.5 * n。
例子:
初始容量是 10。
如果添加第 11 个元素,扩容后容量变为 15。
如果添加第 16 个元素,扩容后容量变为 22(即 15 * 1.5)。
ArrayList 的扩容因子是 1.5。具体来说,当集合元素数量超过当前容量时,ArrayList 的容量会增加到原容量的 150%。
可以通过构造函数设置 ArrayList 的初始容量,但不能直接设置扩容因子。例如:
// 设置初始容量为 20
ArrayList<String> list = new ArrayList<>(20);
无固定容量:LinkedList 根据实际需要动态分配内存,当添加或删除节点时,它会动态地分配内存。因此,LinkedList 不需要考虑扩容因子。
HashMap 使用数组和链表(或红黑树)来存储键值对。在存储的键值对数量超过当前容量的负载因子时,HashMap 会自动扩容。默认情况下,HashMap 的扩容是基于以下规则:
初始容量:默认容量是 16。
扩容因子:负载因子默认值为 0.75。
当 HashMap 中的元素个数超过当前容量的 负载因子(load factor)时,HashMap 会进行扩容。
公式:
threshold = capacity * load factor
例如,默认初始容量是 16,负载因子是 0.75。当 HashMap 中的元素数量超过 16 * 0.75 = 12 时,就会进行扩容。
扩容因子:HashMap 的容量会增加到原容量的 2 倍,即原容量的 200%。
你可以通过构造函数来设置 HashMap 的初始容量和负载因子。
// 初始容量为 32,负载因子为 0.8
HashMap<String, Integer> map = new HashMap<>(32, 0.8f);
扩容规则:同样基于负载因子,当存储的元素个数超过 capacity * load factor 时进行扩容。
扩容因子:容量扩展到原容量的 2 倍,负载因子默认为 0.75。
容器类 | 扩容方式 | 扩容因子 | 初始容量 | 备注 |
---|---|---|---|---|
ArrayList | 1.5 倍扩容 | 1.5 | 10 | 初始容量 10,扩容为 1.5 倍。 |
LinkedList | 不涉及扩容 | 无扩容因子 | 无固定容量 | 基于链表实现,动态分配内存。 |
HashMap | 容量翻倍扩容 | 200% | 16 | 默认负载因子 0.75,容量翻倍。 |
LinkedHashMap | 容量翻倍扩容 | 200% | 16 | 基于 HashMap,保持插入顺序。 |
TreeMap | 不涉及扩容 | 无扩容因子 | 无固定容量 | 基于红黑树实现,自动平衡结构。 |
总的来说,ArrayList 和 HashMap 的扩容方式最为常见,其中 ArrayList 基于 1.5 倍扩容,HashMap 基于负载因子和容量翻倍扩容。而 LinkedList 和 TreeMap 则不涉及容量扩展的概念,因为它们的实现方式不同。
今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!