Java7 HashMap环

📅 2026/6/27 3:10:37
Java7 HashMap环
importjava.util.HashMap;importjava.util.Map;importjava.lang.reflect.Field;/** * 查看 HashMap 环结构的调试版本 * 运行环境JDK 7 */publicclassHashMapCircleDebug{publicstaticvoidmain(String[]args)throwsException{finalMapString,StringmapnewHashMap(2);// 放入两个元素使它们在同一桶中map.put(A0,A);map.put(B0,B);System.out.println(初始状态);printHashMapStructure(map);// 创建两个线程同时 putThreadt1newThread(newRunnable(){Overridepublicvoidrun(){for(inti1;i10000;i){map.put(Ci,C);if(i%100){System.out.println(Thread.currentThread().getName() put Ci);}}}});Threadt2newThread(newRunnable(){Overridepublicvoidrun(){for(inti1;i10000;i){map.put(Di,D);if(i%100){System.out.println(Thread.currentThread().getName() put Di);}}}});t1.start();t2.start();// 等待一段时间让线程执行Thread.sleep(3000);System.out.println(\n 当前 HashMap 结构 );printHashMapStructure(map);// 检查是否形成环System.out.println(\n 检查环 );booleanhasCycledetectCycle(map);System.out.println(是否形成环: hasCycle);if(hasCycle){System.out.println(\n找到环正在打印环的详细信息...);printCycleDetails(map);}// 等待线程结束t1.join();t2.join();}/** * 打印 HashMap 的内部结构 */privatestaticvoidprintHashMapStructure(Map?,?map)throwsException{FieldtableFieldHashMap.class.getDeclaredField(table);tableField.setAccessible(true);Object[]table(Object[])tableField.get(map);if(tablenull){System.out.println(table 为 null);return;}System.out.println(Table 长度: table.length);System.out.println(Size: map.size());for(inti0;itable.length;i){Objectentrytable[i];if(entry!null){System.out.println(\n桶 i:);printLinkedList(entry);}}}/** * 打印链表结构递归方式会检测环 */privatestaticvoidprintLinkedList(Objectentry)throwsException{FieldkeyFieldentry.getClass().getDeclaredField(key);keyField.setAccessible(true);FieldvalueFieldentry.getClass().getDeclaredField(value);valueField.setAccessible(true);FieldnextFieldentry.getClass().getDeclaredField(next);nextField.setAccessible(true);Objectcurrententry;intcount0;// 使用 Map 来检测环java.util.IdentityHashMapObject,Integervisitednewjava.util.IdentityHashMap();while(current!null){// 检测环if(visited.containsKey(current)){System.out.println( ⚠️ 发现环节点 visited.get(current) - 再次回到节点 count);break;}visited.put(current,count);Stringkey(String)keyField.get(current);Stringvalue(String)valueField.get(current);System.out.println( 节点 count: Keykey, Valuevalue (hashCodekey.hashCode()));currentnextField.get(current);count;// 防止无限循环最多打印 50 个if(count50){System.out.println( ... (链表过长已截断));break;}}System.out.println( 链表长度: count 个节点);}/** * 检测 HashMap 中是否存在环 */privatestaticbooleandetectCycle(Map?,?map)throwsException{FieldtableFieldHashMap.class.getDeclaredField(table);tableField.setAccessible(true);Object[]table(Object[])tableField.get(map);if(tablenull)returnfalse;FieldnextFieldnull;for(Objectentry:table){if(entry!null){if(nextFieldnull){nextFieldentry.getClass().getDeclaredField(next);nextField.setAccessible(true);}// 使用快慢指针检测环Objectslowentry;Objectfastentry;while(fast!nullnextField.get(fast)!null){slownextField.get(slow);fastnextField.get(nextField.get(fast));if(slowfast){returntrue;}}}}returnfalse;}/** * 打印环的详细信息 */privatestaticvoidprintCycleDetails(Map?,?map)throwsException{FieldtableFieldHashMap.class.getDeclaredField(table);tableField.setAccessible(true);Object[]table(Object[])tableField.get(map);FieldkeyFieldnull;FieldvalueFieldnull;FieldnextFieldnull;for(Objectentry:table){if(entry!null){if(keyFieldnull){keyFieldentry.getClass().getDeclaredField(key);keyField.setAccessible(true);valueFieldentry.getClass().getDeclaredField(value);valueField.setAccessible(true);nextFieldentry.getClass().getDeclaredField(next);nextField.setAccessible(true);}// 检测这个链表是否有环Objectslowentry;Objectfastentry;booleanhasCyclefalse;while(fast!nullnextField.get(fast)!null){slownextField.get(slow);fastnextField.get(nextField.get(fast));if(slowfast){hasCycletrue;break;}}if(hasCycle){System.out.println(\n找到环);// 找到环的起始点Objectmeetslow;Objectstartentry;while(start!meet){startnextField.get(start);meetnextField.get(meet);}// 打印环中的节点System.out.println(环中的节点);Objectcurrentstart;intcount0;java.util.IdentityHashMapObject,Integervisitednewjava.util.IdentityHashMap();while(current!null!visited.containsKey(current)){visited.put(current,count);Stringkey(String)keyField.get(current);Stringvalue(String)valueField.get(current);System.out.println( [count] Keykey, Valuevalue (hashkey.hashCode()));currentnextField.get(current);count;if(count100)break;}System.out.println(环的大小: visited.size());break;}}}}}