HashMap 什么时候进行扩容呢

本文详细介绍了HashMap的扩容机制,包括何时触发扩容、如何计算新的数组大小以及扩容过程中涉及到的resize操作等核心内容。

HashMap扩容:

  当HashMap中的元素越来越多的时候,碰撞的几率也就越来越高(因为数组的长度是固定的),所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容这个操作也会出现在ArrayList中,所以这是一个通用的操作,很多人对它的性能表示过怀疑,不过想想我们的“均摊”原理,就释然了,而在hashmap数组扩容之后,最消耗性能的点就出现了:原数组中的数据必须重新计算其在新数组中的位置,并放进去,这就是resize。 
  那么HashMap什么时候进行扩容呢?当hashmap中的元素个数超过数组大小*loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,也就是说,默认情况下,数组大小为16,那么当hashmap中元素个数超过16*0.75=12的时候,就把数组的大小扩展为2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知hashmap中元素的个数,那么预设元素的个数能够有效的提高hashmap的性能。比如说,我们有1000个元素new HashMap(1000), 但是理论上来讲new HashMap(1024)更合适,不过上面annegu已经说过,即使是1000,hashmap也自动会将其设置为1024。 但是new HashMap(1024)还不是更合适的,因为0.75*1000 < 1000, 也就是说为了让0.75 * size > 1000, 我们必须这样new HashMap(2048)才最合适,既考虑了&的问题,也避免了resize的问题。

C++ 可以实现类的数组动态扩容。以下是几种常见的实现方式: ### 使用 `new` 和 `delete` 手动管理内存 ```cpp #include <iostream> class MyClass { public: int value; MyClass(int val) : value(val) {} }; int main() { MyClass* arr = new MyClass[2]{MyClass(1), MyClass(2)}; int size = 2; int capacity = 2; // 模拟需要扩容 MyClass* newArr = new MyClass[capacity * 2]; for (int i = 0; i < size; ++i) { newArr[i] = arr[i]; } delete[] arr; arr = newArr; capacity *= 2; // 添加新元素 arr[size++] = MyClass(3); // 输出元素 for (int i = 0; i < size; ++i) { std::cout << arr[i].value << " "; } std::cout << std::endl; delete[] arr; return 0; } ``` 通过手动分配和释放内存,在需要时创建更大的数组并将原数组元素复制过去,实现动态扩容。 ### 使用标准库的 `std::vector` ```cpp #include <iostream> #include <vector> class MyClass { public: int value; MyClass(int val) : value(val) {} }; int main() { std::vector<MyClass> vec; vec.push_back(MyClass(1)); vec.push_back(MyClass(2)); vec.push_back(MyClass(3)); for (const auto& obj : vec) { std::cout << obj.value << " "; } std::cout << std::endl; return 0; } ``` `std::vector` 是 C++ 标准库提供的动态数组容器,会自动管理内存,当空间不足时会自动扩容[^2]。 ### 使用智能指针 ```cpp #include <iostream> #include <memory> class MyClass { public: int value; MyClass(int val) : value(val) {} }; int main() { int size = 2; int capacity = 2; std::unique_ptr<MyClass[]> arr(new MyClass[capacity]{MyClass(1), MyClass(2)}); // 模拟需要扩容 std::unique_ptr<MyClass[]> newArr(new MyClass[capacity * 2]); for (int i = 0; i < size; ++i) { newArr[i] = arr[i]; } arr = std::move(newArr); capacity *= 2; // 添加新元素 arr[size++] = MyClass(3); // 输出元素 for (int i = 0; i < size; ++i) { std::cout << arr[i].value << " "; } std::cout << std::endl; return 0; } ``` 结合 `std::unique_ptr` 可以更安全地管理动态数组内存,避免手动释放内存可能带来的内存泄漏问题。
评论 7
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值