集合嵌套之HashMap嵌套HashMap

本文通过具体案例演示了HashMap集合的嵌套使用,详细介绍了如何利用Java的HashMap来管理多个班级的学生信息及其归属地,展示了双元课堂中不同班级学生数据的组织与遍历方法。

集合嵌套之HashMap嵌套HashMap

  • A:案例演示
    • 集合嵌套之HashMap嵌套HashMap
    • 需求:
    • 双元课堂有很多基础班
    • 第88期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
    • 第99期基础班定义成一个双列集合,键是学生对象,值是学生的归属地
    • 无论88期还是99期都是班级对象,所以为了便于统一管理,把这些班级对象添加到双元课堂集合中
package com.heima.map;

import java.util.HashMap;

import com.heima.bean.Student;

public class Demo08_HashMapHashMap {

	public static void main(String[] args) {
		//定义88期基础班
		HashMap<Student, String> hm88 = new HashMap<>();
		hm88.put(new Student("张三", 23), "北京");
		hm88.put(new Student("李四", 24), "北京");
		hm88.put(new Student("王五", 25), "上海");
		hm88.put(new Student("赵六", 26), "广州");
		
		//定义99期基础班
		HashMap<Student, String> hm99 = new HashMap<>();
		hm99.put(new Student("唐僧", 1023), "北京");
		hm99.put(new Student("孙悟空",1024), "北京");
		hm99.put(new Student("猪八戒",1025), "上海");
		hm99.put(new Student("沙和尚",1026), "广州");
		
		//定义双元课堂
		HashMap<HashMap<Student, String>, String> hm = new HashMap<>();
		hm.put(hm88, "第88期基础班");
		hm.put(hm99, "第99期基础班");
		
		//遍历双列集合
		for(HashMap<Student, String> h : hm.keySet()) {		//hm.keySet()代表的是双列集合中键的集合
			String value = hm.get(h);						//get(h)根据键对象获取值对象
			//遍历键的双列集合对象
			for(Student key : h.keySet()) {					//h.keySet()获取集合总所有的学生键对象
				String value2 = h.get(key);
				
				System.out.println(key + "=" + value2 + "=" + value);
			}
		}
	}
}
### 嵌套十万 HashMap 的性能影响及限制 在 Java 中,嵌套十万个 `HashMap` 会对系统资源和性能产生显著影响。以下是几个关键点的分析: #### 1. 内存占用 每个 `HashMap` 实例本身需要一定的内存开销,包括其内部数组、节点对象以及元数据。如果嵌套十万个 `HashMap`,即使每个 `HashMap` 的初始容量很小(如默认为 16),也会导致巨大的内存消耗。假设每个 `HashMap` 默认大小为 16,负载因子为 0.75,则每个 `HashMap` 最少会分配 16 个桶的空间。根据引用[^2],当元素数量超过 `16 * 0.75 = 12` 时,`HashMap` 会扩容到 32。因此,十万个 `HashMap` 的初始内存需求可能接近以下计算值: ```java // 每个 HashMap 的初始容量为 16 int initialCapacity = 16; // 负载因子为 0.75 float loadFactor = 0.75f; // 十万个 HashMap int numberOfMaps = 100000; // 初始内存估算 long memoryEstimate = numberOfMaps * initialCapacity * 4; // 每个桶约占用 4 字节 System.out.println("Initial Memory Estimate: " + memoryEstimate + " bytes"); ``` 上述代码仅估算初始内存需求,实际内存使用可能会更高,因为 `HashMap` 的内部实现包含额外的元数据。 #### 2. 性能影响 嵌套十万个 `HashMap` 可能会导致以下性能问题: - **初始化开销**:创建十万个 `HashMap` 实例需要大量的 CPU 时间和内存分配操作。 - **垃圾回收压力**:如此多的对象可能导致频繁的垃圾回收(GC),从而降低应用的整体性能。根据引用[^3],即使有 GC 自动回收资源,大量对象的存在仍然可能导致内存溢出(OOM)。 - **哈希冲突**:如果嵌套结构中某些 `HashMap` 存储了大量数据,哈希冲突的可能性会增加,进而降低查找效率。根据引用[^2],良好的哈希函数设计可以缓解这一问题,但无法完全避免。 #### 3. 扩展性限制 - **JVM 堆内存限制**:嵌套十万个 `HashMap` 可能超出 JVM 的堆内存限制,尤其是在 32 位系统或配置较低的服务器上。根据引用[^3],Android 系统对应用的内存限制更加严格,容易引发 OOM。 - **线程安全**:如果这些 `HashMap` 在多线程环境中使用,同步机制会进一步增加性能开销。 #### 示例代码 以下是一个简单的示例,展示如何创建嵌套的 `HashMap` 并评估其性能: ```java import java.util.HashMap; public class NestedHashMapTest { public static void main(String[] args) { int numberOfMaps = 100000; HashMap<Integer, HashMap<Integer, Integer>> nestedMap = new HashMap<>(); long startTime = System.currentTimeMillis(); for (int i = 0; i < numberOfMaps; i++) { nestedMap.put(i, new HashMap<>()); } long endTime = System.currentTimeMillis(); System.out.println("Time taken to create " + numberOfMaps + " HashMaps: " + (endTime - startTime) + " ms"); System.out.println("Memory usage: " + (Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()) / 1024 / 1024 + " MB"); } } ``` 运行上述代码可以帮助评估嵌套十万 `HashMap` 的时间和内存开销。 ### 结论 嵌套十万个 `HashMap` 是可行的,但会对系统资源和性能产生显著影响。为了优化性能,建议考虑以下替代方案: - 使用单层 `HashMap` 或其他数据结构(如 `TreeMap` 或 `ConcurrentHashMap`)。 - 如果必须嵌套,尽量减少层级和实例数量。 - 预先设置合适的初始容量以避免频繁扩容。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

左绍骏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值