Java LinkedHashMap案例如何用

wen java案例 26

Java LinkedHashMap 实用案例

LinkedHashMap 基础特性

LinkedHashMap 继承自 HashMap,但保留了元素的插入顺序访问顺序

Java LinkedHashMap案例如何用

基本使用案例

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);
    }
}

使用建议

  1. 需要保持插入顺序:使用默认构造器 new LinkedHashMap<>()
  2. 实现 LRU 缓存:使用 new LinkedHashMap<>(capacity, 0.75f, true) 并重写 removeEldestEntry
  3. 内存考虑:LinkedHashMap 比 HashMap 多维护一个双向链表,占用更多内存
  4. 性能:基本操作与 HashMap 相近,迭代稍快(因为维护了链表)
  5. 线程安全:非线程安全,多线程环境需要使用 Collections.synchronizedMap()

这些案例涵盖了 LinkedHashMap 的主要使用场景,从简单的顺序保持到复杂的 LRU 缓存实现。

抱歉,评论功能暂时关闭!