java 中 LinkedHashMap使用总结

本文详细介绍了Java中的LinkedHashMap,它是HashMap和LinkedList的结合体,保证了元素迭代的顺序。LinkedHashMap通过维护一个双向链表,解决了HashMap无序的问题。文章探讨了LinkedHashMap的基本数据结构、初始化过程、添加元素的实现,并展示了如何利用LinkedHashMap实现LRU算法的缓存机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

初识LinkedHashMap

上两篇文章讲了HashMap和HashMap在多线程下引发的问题,说明了,HashMap是一种非常常见、非常有用的集合,并且在多线程情况下使用不当会有线程安全问题。

大多数情况下,只要不涉及线程安全问题,Map基本都可以使用HashMap,不过HashMap有一个问题,就是迭代HashMap的顺序并不是HashMap放置的顺序,也就是无序。HashMap的这一缺点往往会带来困扰,因为有些场景,我们期待一个有序的Map。

这个时候,LinkedHashMap就闪亮登场了,它虽然增加了时间和空间上的开销,但是通过维护一个运行于所有条目的双向链表,LinkedHashMap保证了元素迭代的顺序

 

四个关注点在LinkedHashMap上的答案

关  注  点 结      论
LinkedHashMap是否允许键值对为空 Key和Value都允许空
LinkedHashMap是否允许重复数据 Key重复会覆盖、Value允许重复
LinkedHashMap是否有序 有序
LinkedHashMap是否线程安全 非线程安全

 

LinkedHashMap基本数据结构

关于LinkedHashMap,先提两点:

1、LinkedHashMap可以认为是HashMap+LinkedList,即它既使用HashMap操作数据结构,又使用LinkedList维护插入元素的先后顺序

2、LinkedHashMap的基本实现思想就是----多态。可以说,理解多态,再去理解LinkedHashMap原理会事半功倍;反之也是,对于LinkedHashMap原理的学习,也可以促进和加深对于多态的理解。

为什么可以这么说,首先看一下,LinkedHashMap的定义:

public class LinkedHashMap<K,V>
    extends HashMap<K,V>
    implements Map<K,V>
{
    ...
}

看到,LinkedHashMap是HashMap的子类,自然LinkedHashMap也就继承了HashMap中所有非private的方法。再看一下LinkedHashMap中本身的方法:

看到LinkedHashMap中并没有什么操作数据结构的方法,也就是说LinkedHashMap操作数据结构(比如put一个数据),和HashMap操作数据的方法完全一样,无非就是细节上有一些的不同罢了。

LinkedHashMap和HashMap的区别在于它们的基本数据结构上,看一下LinkedHashMap的基本数据结构,也就是Entry:

复制代码
private static class Entry<K,V> extends HashMap.Entry<K,V> {
    // These fields comprise the doubly linked list used for iteration.
    Entry<K,V> before, after;

Entry(int hash, K key, V value, HashMap.Entry<K,V> next) {
        super(hash, key, value, next);
    }
    ...
}
复制代码

列一下Entry里面有的一些属性吧:

  • K key
  • V value
  • Entry<K, V> next
  • int hash
  • Entry<K, V> before
  • Entry<K, V> after

其中前面四个,也就是红色部分是从HashMap.Entry中继承过来的;后面两个,也就是蓝色部分是LinkedHashMap独有的。不要搞错了next和before、After,next是用于维护HashMap指定table位置上连接的Entry的顺序的,before、After是用于维护Entry插入的先后顺序的

还是用图表示一下,列一下属性而已:

 

初始化LinkedHashMap

假如有这么一段代码:

复制代码
1 public static void main(String[] args)
2 {
3     LinkedHashMap<String, String> linkedHashMap =
4             new LinkedHashMap<String, String>();
### Java 中遍历 LinkedHashMap 的方法 在 Java 中,`LinkedHashMap` 是 `HashMap` 的子类,它保留了插入顺序或访问顺序。因此,在遍历 `LinkedHashMap` 时,可以按照其内部维护的顺序来获取键值对。以下是几种常见的遍历方式。 #### 方法一:使用增强型 for 循环 通过 `entrySet()` 方法可以获得 `LinkedHashMap` 中所有的键值对集合,然后使用增强型 for 循环逐一访问这些键值对: ```java import java.util.LinkedHashMap; import java.util.Map; public class IterateLinkedHashMapExample { public static void main(String[] args) { LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put(11, "AB"); linkedHashMap.put(2, "CD"); linkedHashMap.put(33, "EF"); System.out.println("Using Enhanced For Loop:"); for (Map.Entry<Integer, String> entry : linkedHashMap.entrySet()) { System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue()); } } } ``` 此方法简单直观,适用于大多数场景[^1]。 --- #### 方法二:使用 Iterator 进行迭代 如果需要更灵活地控制迭代过程(例如中途停止迭代),可以通过 `Iterator` 来实现: ```java import java.util.Iterator; import java.util.LinkedHashMap; import java.util.Map; public class IterateWithIteratorExample { public static void main(String[] args) { LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put(11, "AB"); linkedHashMap.put(2, "CD"); linkedHashMap.put(33, "EF"); System.out.println("Using Iterator:"); Iterator<Map.Entry<Integer, String>> iterator = linkedHashMap.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<Integer, String> entry = iterator.next(); System.out.println("Key: " + entry.getKey() + ", Value: " + entry.getValue()); } } } ``` 这种方法提供了更多的灵活性,尤其是在需要条件判断的情况下[^2]。 --- #### 方法三:使用 Lambda 表达式和 forEach() 自 Java 8 起,引入了函数式编程特性,允许使用 `forEach()` 和 Lambda 表达式简化代码结构: ```java import java.util.LinkedHashMap; import java.util.Map; public class IterateWithLambdaExample { public static void main(String[] args) { LinkedHashMap<Integer, String> linkedHashMap = new LinkedHashMap<>(); linkedHashMap.put(11, "AB"); linkedHashMap.put(2, "CD"); linkedHashMap.put(33, "EF"); System.out.println("Using Lambda Expression and forEach():"); linkedHashMap.forEach((key, value) -> { System.out.println("Key: " + key + ", Value: " + value); }); } } ``` 这种方式更加简洁明了,尤其适合现代开发环境中的需求[^1]。 --- ### 总结 以上三种方法都可以用于遍历 `LinkedHashMap`,具体选择取决于实际应用场景和个人偏好。对于简单的遍历操作,推荐使用增强型 for 循环;而对于需要更多控制权的情况,则可以选择 `Iterator` 或者结合 Java 8 特性的 `forEach()` 方法。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值