Java LinkedHashMap 实用案例
LinkedHashMap 基础特性
LinkedHashMap 继承自 HashMap,但保留了元素的插入顺序或访问顺序。

基本使用案例
1 保持插入顺序
import java.util.LinkedHashMap;
import java.util.Map;
public class InsertionOrderExample {
public static void main(String[] args) {
// 默认构造器:保持插入顺序
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.put("D", 4);
System.out.println("插入顺序遍历:");
for (Map.Entry<String, Integer> entry : map.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
// 输出:A -> 1, B -> 2, C -> 3, D -> 4
}
}
2 基于访问顺序的 LRU 缓存
import java.util.LinkedHashMap;
import java.util.Map;
public class AccessOrderExample {
public static void main(String[] args) {
// 第三个参数 true 表示按照访问顺序
LinkedHashMap<String, Integer> map = new LinkedHashMap<>(16, 0.75f, true);
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
map.put("D", 4);
System.out.println("初始顺序:");
System.out.println(map); // {A=1, B=2, C=3, D=4}
// 访问元素
map.get("B");
map.get("D");
System.out.println("访问 B 和 D 后的顺序:");
System.out.println(map); // {A=1, C=3, B=2, D=4}
// 最近访问的 B 和 D 移到了末尾
}
}
实现 LRU 缓存(经典案例)
import java.util.LinkedHashMap;
import java.util.Map;
class LRUCache<K, V> extends LinkedHashMap<K, V> {
private final int maxSize;
public LRUCache(int maxSize) {
// 初始化容量,负载因子,访问顺序
super(maxSize, 0.75f, true);
this.maxSize = maxSize;
}
// 重写 removeEldestEntry 方法,当缓存满时移除最旧元素
@Override
protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
return size() > maxSize;
}
}
public class LRUCacheExample {
public static void main(String[] args) {
LRUCache<Integer, String> cache = new LRUCache<>(3);
cache.put(1, "One");
cache.put(2, "Two");
cache.put(3, "Three");
System.out.println("初始缓存: " + cache);
// 输出:{1=One, 2=Two, 3=Three}
// 访问 key=1,使其成为最近使用
cache.get(1);
// 添加新元素,此时会移除最久未使用的元素(key=2)
cache.put(4, "Four");
System.out.println("添加 4 后: " + cache);
// 输出:{3=Three, 1=One, 4=Four}
// 再次访问 3
cache.get(3);
// 添加 5,移除 1(最久未使用)
cache.put(5, "Five");
System.out.println("添加 5 后: " + cache);
// 输出:{4=Four, 3=Three, 5=Five}
}
}
用户访问日志统计
import java.util.LinkedHashMap;
import java.util.Map;
public class UserAccessLogExample {
public static void main(String[] args) {
// 记录用户最近访问的页面,最多保存 5 条
recentPages();
// 记录用户访问频率
accessFrequency();
}
// 记录最近访问页面
public static void recentPages() {
LinkedHashMap<String, String> recentPages = new LinkedHashMap<>(5, 0.75f, true) {
@Override
protected boolean removeEldestEntry(Map.Entry<String, String> eldest) {
return size() > 5;
}
};
// 模拟用户访问
recentPages.put("user1", "/home");
recentPages.put("user2", "/products");
recentPages.put("user1", "/cart");
recentPages.put("user3", "/checkout");
recentPages.put("user1", "/orders");
recentPages.put("user4", "/profile");
System.out.println("最近访问的用户界面:");
for (Map.Entry<String, String> entry : recentPages.entrySet()) {
System.out.println(entry.getKey() + " 最后访问: " + entry.getValue());
}
}
// 记录访问频率
public static void accessFrequency() {
// 保持插入顺序的记录
LinkedHashMap<String, Integer> accessCount = new LinkedHashMap<>();
String[] pages = {"/home", "/products", "/home", "/about",
"/home", "/products", "/contact", "/products"};
for (String page : pages) {
accessCount.merge(page, 1, Integer::sum);
}
System.out.println("\n页面访问统计(按首次访问顺序):");
for (Map.Entry<String, Integer> entry : accessCount.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue() + " 次");
}
}
}
自定义排序的配置系统
import java.util.LinkedHashMap;
import java.util.Map;
public class ConfigSystemExample {
public static void main(String[] args) {
// 保持配置项的添加顺序
LinkedHashMap<String, Object> systemConfig = new LinkedHashMap<>();
// 添加配置项(保持顺序很重要,比如数据库配置必须在应用配置之前)
addEssentialConfig(systemConfig);
addDatabaseConfig(systemConfig);
addApplicationConfig(systemConfig);
System.out.println("系统配置(按重要顺序):");
for (Map.Entry<String, Object> entry : systemConfig.entrySet()) {
System.out.println(entry.getKey() + " = " + entry.getValue());
}
}
private static void addEssentialConfig(LinkedHashMap<String, Object> config) {
config.put("server.port", 8080);
config.put("server.host", "localhost");
}
private static void addDatabaseConfig(LinkedHashMap<String, Object> config) {
config.put("db.url", "jdbc:mysql://localhost:3306/mydb");
config.put("db.username", "admin");
config.put("db.password", "secret");
}
private static void addApplicationConfig(LinkedHashMap<String, Object> config) {
config.put("app.name", "MyApp");
config.put("app.version", "1.0.0");
config.put("app.debug", true);
}
}
性能测试与对比
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
public class PerformanceComparison {
public static void main(String[] args) {
int size = 100000;
// 测试插入性能
long startTime = System.nanoTime();
LinkedHashMap<Integer, String> linkedMap = new LinkedHashMap<>();
for (int i = 0; i < size; i++) {
linkedMap.put(i, "Value" + i);
}
long linkedTime = System.nanoTime() - startTime;
startTime = System.nanoTime();
HashMap<Integer, String> hashMap = new HashMap<>();
for (int i = 0; i < size; i++) {
hashMap.put(i, "Value" + i);
}
long hashTime = System.nanoTime() - startTime;
System.out.println("插入 " + size + " 条数据:");
System.out.println("LinkedHashMap: " + linkedTime / 1_000_000 + " ms");
System.out.println("HashMap: " + hashTime / 1_000_000 + " ms");
// 测试遍历性能(保持顺序)
startTime = System.nanoTime();
for (Map.Entry<Integer, String> entry : linkedMap.entrySet()) {
// 模拟操作
}
linkedTime = System.nanoTime() - startTime;
System.out.println("\n遍历性能:");
System.out.println("LinkedHashMap: " + linkedTime / 1_000_000 + " ms");
}
}
实用技巧总结
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapTips {
public static void main(String[] args) {
// 1. 反向迭代
LinkedHashMap<String, Integer> map = new LinkedHashMap<>();
map.put("A", 1);
map.put("B", 2);
map.put("C", 3);
System.out.println("反向迭代:");
String[] keys = map.keySet().toArray(new String[0]);
for (int i = keys.length - 1; i >= 0; i--) {
System.out.println(keys[i] + " -> " + map.get(keys[i]));
}
// 2. 获取第一个和最后一个元素
if (!map.isEmpty()) {
String firstKey = map.keySet().iterator().next();
System.out.println("\n第一个元素:" + firstKey + " -> " + map.get(firstKey));
}
// 3. 使用 computeIfAbsent
map.computeIfAbsent("D", k -> 4);
System.out.println("\n使用 computeIfAbsent 添加 D: " + map);
// 4. 批量操作
map.replaceAll((k, v) -> v * 2);
System.out.println("所有值乘以 2: " + map);
// 5. 安全的迭代删除
System.out.println("\n安全删除值小于 3 的元素:");
map.entrySet().removeIf(entry -> entry.getValue() < 3);
System.out.println(map);
}
}
使用建议
- 需要保持插入顺序:使用默认构造器
new LinkedHashMap<>() - 实现 LRU 缓存:使用
new LinkedHashMap<>(capacity, 0.75f, true)并重写removeEldestEntry - 内存考虑:LinkedHashMap 比 HashMap 多维护一个双向链表,占用更多内存
- 性能:基本操作与 HashMap 相近,迭代稍快(因为维护了链表)
- 线程安全:非线程安全,多线程环境需要使用
Collections.synchronizedMap()
这些案例涵盖了 LinkedHashMap 的主要使用场景,从简单的顺序保持到复杂的 LRU 缓存实现。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播