LinkedHashMap<K, V>
LinkedHashMap<K, V>
是 Java 集合框架中的一个重要类,它继承自 HashMap<K, V>
,同时实现了 Map<K, V>
接口。下面从多个方面详细介绍 LinkedHashMap<K, V>
。
特性
- 键值对存储:和
HashMap
一样,LinkedHashMap
以键值对(key - value
)形式存储数据,每个键是唯一的,键和值都可以为null
。 - 有序性:这是
LinkedHashMap
区别于HashMap
的关键特性。它可以保持插入顺序或者访问顺序。插入顺序指的是元素按照插入的先后顺序排列;访问顺序指的是每次访问(如get
操作)一个元素后,该元素会被移动到链表尾部,最久未被访问的元素在链表头部。 - 基于哈希表和双向链表实现:
LinkedHashMap
内部维护了一个双向链表,用于记录元素的顺序,同时使用哈希表来实现快速的键值查找。
构造方法
LinkedHashMap()
:创建一个默认初始容量为 16,负载因子为 0.75,按照插入顺序排序的空LinkedHashMap
。
import java.util.LinkedHashMap; import java.util.Map; public class LinkedHashMapExample { public static void main(String[] args) { LinkedHashMap<String, Integer> map = new LinkedHashMap<>(); } }
LinkedHashMap(int initialCapacity)
:创建一个指定初始容量,负载因子为 0.75,按照插入顺序排序的空LinkedHashMap
。
LinkedHashMap<String, Integer> map = new LinkedHashMap<>(32);
LinkedHashMap(int initialCapacity, float loadFactor)
:创建一个指定初始容量和负载因子,按照插入顺序排序的空LinkedHashMap
。
LinkedHashMap<String, Integer> map = new LinkedHashMap<>(32, 0.8f);
LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)
:创建一个指定初始容量、负载因子和排序方式的空LinkedHashMap
。当accessOrder
为true
时,按照访问顺序排序;为false
时,按照插入顺序排序。
LinkedHashMap<String, Integer> map = new LinkedHashMap<>(32, 0.8f, true);
LinkedHashMap(Map<? extends K, ? extends V> m)
:创建一个包含指定Map
中所有键值对,按照插入顺序排序的LinkedHashMap
。
import java.util.HashMap; import java.util.Map; public class LinkedHashMapExample { public static void main(String[] args) { Map<String, Integer> anotherMap = new HashMap<>(); anotherMap.put("apple", 1); LinkedHashMap<String, Integer> map = new LinkedHashMap<>(anotherMap); } }
常用方法
LinkedHashMap
继承了 HashMap
的大部分方法,同时也有一些自身的特点,以下是一些常用方法:
- 插入和更新操作put(K key, V value):将指定的键值对插入到 LinkedHashMap 中。如果键已经存在,则更新该键对应的值。返回该键之前关联的值,如果键不存在则返回 null。
LinkedHashMap<String, Integer> map = new LinkedHashMap<>(); Integer oldValue = map.put("apple", 1);
- **`putAll(Map<? extends K, ? extends V> m)`**:将指定 `Map` 中的所有键值对复制到当前 `LinkedHashMap` 中。
Map<String, Integer> anotherMap = new HashMap<>(); anotherMap.put("banana", 2); map.putAll(anotherMap);
- 删除操作remove(Object key):从 LinkedHashMap 中移除指定键对应的键值对。返回该键关联的值,如果键不存在则返回 null。
Integer removedValue = map.remove("apple");
- 查询操作get(Object key):返回指定键关联的值,如果键不存在则返回 null。当 accessOrder 为 true 时,该操作会将访问的元素移动到链表尾部。
Integer value = map.get("apple");
- **`containsKey(Object key)`**:判断 `LinkedHashMap` 中是否包含指定的键,包含返回 `true`,否则返回 `false`。
boolean hasKey = map.containsKey("apple");
- **`containsValue(Object value)`**:判断 `LinkedHashMap` 中是否包含指定的值,包含返回 `true`,否则返回 `false`。
boolean hasValue = map.containsValue(1);
- **`size()`**:返回 `LinkedHashMap` 中键值对的数量。
int size = map.size();
- 遍历操作entrySet():返回一个包含 LinkedHashMap 中所有键值对的 Set 视图,每个键值对用 Map.Entry<K, V> 对象表示。遍历该 Set 可以按照插入顺序或访问顺序获取键值对。
import java.util.LinkedHashMap; import java.util.Map; public class LinkedHashMapTraversal { public static void main(String[] args) { LinkedHashMap<String, Integer> map = new LinkedHashMap<>(); map.put("apple", 1); map.put("banana", 2); map.put("cherry", 3); for (Map.Entry<String, Integer> entry : map.entrySet()) { String key = entry.getKey(); Integer value = entry.getValue(); System.out.println("Key: " + key + ", Value: " + value); } } }
应用场景
- 缓存实现:由于
LinkedHashMap
可以按照访问顺序排序,因此可以很方便地实现 LRU(Least Recently Used,最近最少使用)缓存。当缓存满时,移除链表头部最久未被访问的元素。
import java.util.LinkedHashMap; import java.util.Map; public class LRUCache<K, V> extends LinkedHashMap<K, V> { private final int capacity; public LRUCache(int capacity) { super(capacity, 0.75f, true) { @Override protected boolean removeEldestEntry(Map.Entry<K, V> eldest) { return size() > capacity; } }; this.capacity = capacity; } public static void main(String[] args) { LRUCache<String, Integer> cache = new LRUCache<>(3); cache.put("apple", 1); cache.put("banana", 2); cache.put("cherry", 3); System.out.println(cache); cache.get("apple"); System.out.println(cache); cache.put("date", 4); System.out.println(cache); } }
注意事项
- 性能:
LinkedHashMap
的插入、删除和查找操作的时间复杂度与HashMap
相同,都是。但由于需要维护双向链表,会有一些额外的开销。
- 线程安全:
LinkedHashMap
不是线程安全的,如果需要在多线程环境下使用,可以考虑使用Collections.synchronizedMap
方法将其包装成线程安全的Map
。
import java.util.Collections; import java.util.LinkedHashMap; import java.util.Map; Map<String, Integer> synchronizedMap = Collections.synchronizedMap(new LinkedHashMap<>());
综上所述,LinkedHashMap
是一个非常实用的集合类,适合需要保持元素顺序的场景,尤其是实现缓存时非常方便。
Java集合框架 文章被收录于专栏
Java集合框架是Java提供的一组用于存储和操作数据的类和接口,它位于java.util包中,为开发者提供了强大且灵活的数据存储和处理能力。以下将从整体架构、主要接口、常用实现类、使用场景以及示例代码等方面详细介绍Java集合框架。