网站名称和备案的不一样网站开发软硬件
2026/3/14 0:22:46 网站建设 项目流程
网站名称和备案的不一样,网站开发软硬件,江苏企业网站排名优化,discuz x3 wordpress在Java中#xff0c;LinkedHashMap 是HashMap的一个子类#xff0c;它维护了一个双向链表来记录插入顺序或访问顺序。LinkedHashMap的底层构成LinkedHashMap是在HashMap的基础上#xff0c;增加了双向链表来维护顺序。1. 核心数据结构// LinkedHashMap内部类Entry继承了Hash…在Java中LinkedHashMap是HashMap的一个子类它维护了一个双向链表来记录插入顺序或访问顺序。LinkedHashMap的底层构成LinkedHashMap是在HashMap的基础上增加了双向链表来维护顺序。1.核心数据结构// LinkedHashMap内部类Entry继承了HashMap.Node static class EntryK,V extends HashMap.NodeK,V { EntryK,V before, after; // 双向链表指针 Entry(int hash, K key, V value, NodeK,V next) { super(hash, key, value, next); } }2.实际存储结构HashMap部分: 数组 链表/红黑树解决哈希冲突 LinkedHashMap额外部分: 头节点(head) ↔ 节点1 ↔ 节点2 ↔ ... ↔ 尾节点(tail)双向链表主要特点1.有序性插入顺序默认按元素插入的顺序维护访问顺序可通过构造函数设置为按访问顺序维护2.继承关系Object ↳ AbstractMapK,V ↳ HashMapK,V ↳ LinkedHashMapK,V基本用法import java.util.LinkedHashMap; import java.util.Map; public class LinkedHashMapExample { public static void main(String[] args) { // 1. 创建LinkedHashMap默认按插入顺序 LinkedHashMapString, Integer linkedMap new LinkedHashMap(); // 添加元素 linkedMap.put(Apple, 100); linkedMap.put(Banana, 50); linkedMap.put(Orange, 80); linkedMap.put(Grape, 120); // 遍历 - 按插入顺序输出 System.out.println(按插入顺序:); for (Map.EntryString, Integer entry : linkedMap.entrySet()) { System.out.println(entry.getKey() : entry.getValue()); } // 输出: Apple, Banana, Orange, Grape按插入顺序 // 2. 按访问顺序LRU顺序 LinkedHashMapString, Integer lruMap new LinkedHashMap( 16, // 初始容量 0.75f, // 加载因子 true // accessOrder为true表示按访问顺序 ); lruMap.put(A, 1); lruMap.put(B, 2); lruMap.put(C, 3); System.out.println(\n访问前:); lruMap.forEach((k, v) - System.out.print(k )); // A B C // 访问元素B lruMap.get(B); System.out.println(\n访问B后:); lruMap.forEach((k, v) - System.out.print(k )); // A C B } }构造方法// 1. 默认构造函数插入顺序初始容量16加载因子0.75 LinkedHashMapString, Integer map1 new LinkedHashMap(); // 2. 指定初始容量 LinkedHashMapString, Integer map2 new LinkedHashMap(32); // 3. 指定初始容量和加载因子 LinkedHashMapString, Integer map3 new LinkedHashMap(32, 0.8f); // 4. 指定初始容量、加载因子和排序模式 // true: 按访问顺序 false: 按插入顺序默认 LinkedHashMapString, Integer map4 new LinkedHashMap(32, 0.75f, true); // 5. 从其他Map复制 LinkedHashMapString, Integer map5 new LinkedHashMap(existingMap);与HashMap比较特性HashMapLinkedHashMap顺序无顺序插入顺序或访问顺序性能O(1)略慢于HashMap需要维护链表内存占用较少较多需要额外存储链表指针迭代性能较慢需要遍历整个table较快直接遍历链表哈希存储过程计算哈希通过key.hashCode()计算定位桶(n-1) hash计算数组下标处理冲突链表或红黑树维护顺序同时添加到双向链表的尾部详细工作原理图HashMap结构快速查找 LinkedHashMap额外结构维护顺序 ↓ ↓ ┌───────┐ head → tail │ 数组 │ ↑ ↓ │[0] │ ┌─────┐ ┌─────┐ ┌─────┐ 插入A → 哈希 → │[1] → A│───────────────→│ A │←→│ │ │ │ │[2] │ └─────┘ └─────┘ └─────┘ │[3] │ └───────┘ ┌───────┐ head → tail │ 数组 │ ↑ ↓ │[0] │ ┌─────┐ ┌─────┐ ┌─────┐ 插入B → 哈希 → │[1] → A│───────────────→│ A │←→│ B │ │ │ │[2] → B│───────────────→│ │←→│ │ │ │ │[3] │ └─────┘ └─────┘ └─────┘ └───────┘ ┌───────┐ head → tail │ 数组 │ ↑ ↓ │[0] │ ┌─────┐ ┌─────┐ ┌─────┐ 插入C → 哈希 → │[1] → A│───────────────→│ A │←→│ B │←→│ C │ │[2] → B│───────────────→│ │←→│ │←→│ │ │[3] → C│───────────────→│ │←→│ │←→│ │ └───────┘ └─────┘ └─────┘ └─────┘源码关键方法解析// 1. 创建节点时同时链接到链表尾部 NodeK,V newNode(int hash, K key, V value, NodeK,V e) { LinkedHashMap.EntryK,V p new LinkedHashMap.Entry(hash, key, value, e); linkNodeLast(p); // ← 关键将新节点链接到链表尾部 return p; } // 2. 链接节点到链表尾部 private void linkNodeLast(LinkedHashMap.EntryK,V p) { LinkedHashMap.EntryK,V last tail; tail p; if (last null) head p; else { p.before last; last.after p; } } // 3. 访问节点后调整顺序LRU模式 void afterNodeAccess(NodeK,V e) { // 移动节点到链表尾部 LinkedHashMap.EntryK,V last; if (accessOrder (last tail) ! e) { LinkedHashMap.EntryK,V p (LinkedHashMap.EntryK,V)e, b p.before, a p.after; p.after null; if (b null) head a; else b.after a; if (a ! null) a.before b; else last b; if (last null) head p; else { p.before last; last.after p; } tail p; modCount; } }查找过程示例public class LookupExample { public static void main(String[] args) { LinkedHashMapString, Integer map new LinkedHashMap(); map.put(Apple, 100); map.put(Banana, 50); map.put(Orange, 80); // 查找Banana的过程 // 1. 计算hash: Banana.hashCode() // 2. 定位桶: (n-1) hash → 找到数组下标 // 3. 遍历链表/树: 在对应桶中查找 // 4. 如果accessOrdertrue调用afterNodeAccess()将节点移到链表尾部 Integer value map.get(Banana); // 通过哈希快速定位 System.out.println(Found: value); } }性能特点对比操作HashMapLinkedHashMap查找O(1)O(1)同样使用哈希插入O(1)O(1)额外链表操作删除O(1)O(1)额外链表操作迭代O(n)O(n)但更快直接遍历链表内存较小每个节点多2个引用before, after总结底层构成HashMap的数组链表/红黑树 额外的双向链表key哈希完全使用HashMap的哈希机制确保O(1)查找顺序维护通过双向链表维护插入顺序或访问顺序设计巧妙结合了HashMap的快速查找和链表的顺序特性LinkedHashMap通过这种哈希表双向链表的复合结构既保证了HashMap的快速查找特性又提供了可预测的迭代顺序是一个非常精妙的设计进阶问题LinkedHashMap作为一个Map与HashMap基本相同为什么还需要添加一个排序功能创造出LinkedHashMap确实作为Map核心功能是通过key找value。但维护顺序在很多实际场景中非常有用让我通过具体例子来解释1.需要保持插入顺序的场景示例配置文件解析public class ConfigFileParser { public static void main(String[] args) { // 读取配置文件需要保持原有顺序 LinkedHashMapString, String config new LinkedHashMap(); config.put(server.host, localhost); config.put(server.port, 8080); config.put(database.url, jdbc:mysql://localhost:3306/mydb); config.put(database.username, admin); config.put(database.password, secret); // 保存配置时保持原来的顺序 System.out.println(配置项保持原顺序:); config.forEach((key, value) - System.out.println(key value)); // 输出顺序与插入顺序一致便于阅读和维护 } }示例操作日志记录public class OperationLogger { public static void main(String[] args) { // 记录用户操作序列 LinkedHashMapLong, String operationLog new LinkedHashMap(); operationLog.put(System.currentTimeMillis(), 用户登录); Thread.sleep(100); operationLog.put(System.currentTimeMillis(), 查询商品); Thread.sleep(100); operationLog.put(System.currentTimeMillis(), 添加购物车); Thread.sleep(100); operationLog.put(System.currentTimeMillis(), 提交订单); // 可以按操作发生的顺序回放 System.out.println(用户操作序列:); operationLog.forEach((time, op) - System.out.println(new Date(time) - op)); } }2.需要可预测迭代顺序的场景示例生成有序的JSON/XMLpublic class OrderedJSONGenerator { public static void main(String[] args) { // 使用LinkedHashMap保证JSON字段顺序 LinkedHashMapString, Object json new LinkedHashMap(); json.put(id, 1001); json.put(name, 张三); json.put(age, 25); json.put(email, zhangsanexample.com); json.put(createdAt, 2024-01-15); // 转换为JSON时字段顺序是确定的 String jsonString convertToJSON(json); System.out.println(jsonString); // 输出{id:1001,name:张三,age:25,email:zhangsanexample.com,createdAt:2024-01-15} // 如果不保证顺序每次输出可能不同不利于调试和测试 } static String convertToJSON(LinkedHashMapString, Object map) { StringBuilder sb new StringBuilder({); for (Map.EntryString, Object entry : map.entrySet()) { sb.append(\).append(entry.getKey()).append(\:); sb.append(\).append(entry.getValue()).append(\,); } sb.deleteCharAt(sb.length() - 1); sb.append(}); return sb.toString(); } }3.构建有序映射表示例字母频率统计按字母顺序public class LetterFrequency { public static void main(String[] args) { String text hello world; // 使用LinkedHashMap按字母顺序统计 LinkedHashMapCharacter, Integer frequency new LinkedHashMap(); // 先初始化所有字母保证顺序 for (char c a; c z; c) { frequency.put(c, 0); } // 统计频率 for (char c : text.toLowerCase().toCharArray()) { if (frequency.containsKey(c)) { frequency.put(c, frequency.get(c) 1); } } // 按字母顺序输出 System.out.println(字母频率统计:); frequency.forEach((letter, count) - { if (count 0) { System.out.println(letter : count); } }); // 输出d:1, e:1, h:1, l:3, o:2, r:1, w:1 } }核心价值LinkedHashMap在不牺牲查找性能O(1)的前提下提供了可预测的迭代顺序这在很多业务场景中非常有用。它结合了HashMap的快速查找和List的顺序特性是一个两全其美的数据结构。所以虽然Map的核心是通过key找value但顺序在很多实际应用中提供了额外的价值而LinkedHashMap正好满足了这个需求

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询