在Java中的LinkedHashMap
LinkedHashMap是一个散列和链接的基于列表的Map接口实现,具有可预测的插入顺序。
它保持所有条目的双链接列表,这就是它与HashMap的不同之处。
java linkedhashmap.
关于LinkedHashMap的一些说明
- LinkedHashMap实现映射接口并扩展HashMap类。
- LinkedHashMap维护插入顺序,因此当我们能够按顺序访问元素时,它们会像ArrayList一样访问。
- LinkedHashMap维护双链接列表以维护插入顺序。
- 它不同步,并且不是线程安全的。
- 不允许重复键
- 一个
nullkey和多个null值是允许的
linkedhashmap构造函数
Java LinkedHashMap类有五个构造函数
public LinkedHashMap():这是默认构造函数,主要用于。
它创建一个空的LinkedHashMap,默认初始容量为16,负载因子0.75.public LinkedHashMap(int initialCapacity):此构造函数用于指定LinkedHashMap和默认负载因子0.75的初始容量。public LinkedHashMap(int initialCapacity,float loadFactor):此构造函数用于指定LinkedHashMap和负载因子的初始容量。
在大多数场景中,我们应该避免使用此构造函数,除非我们确定这一点,因为负载因子0.75提供时间和空间之间的良好权衡。public LinkedHashMap(Map<? extends K,? extends V> m):当我们希望从Treemap或者HashMap等其他映射(Map)中创建LinkedHashMap时使用此构造函数。
public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder):此构造函数用于指定HashMap的初始容量,负载因子和访问顺序。
如果我们将访问命令传递为true,那么它将基于访问顺序列出条目。
将键值对添加到linkedhashmap
我们可以用 put()添加条目的方法 LinkedHashMap类似于HashMap。
例子:
package org.igi.theitroad;
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapEntriesMain {
public static void main(String[] args) {
Map<Integer, String> studentMap = new LinkedHashMap<Integer, String>();
//Putting key-values pairs in LinkedHashMap
studentMap.put(1, "Arvind");
studentMap.put(2, "Andy");
studentMap.put(3, "Mohan");
studentMap.put(4, "Virat");
System.out.println(studentMap);
}
}
运行上面的程序时,我们将得到以下输出
{1=Arvind, 2=Andy, 3=Mohan, 4=Virat}
正如我们所看到的,所有条目都按预期打印为插入顺序。
如果我们只想在LinkedHashMap中尚未存在时才能添加条目,那么我们可以使用 putIfAbsent()这种情况下的方法。
After Java 7, you can use diamond operator(<>) to initialize Map. You can change Map<Integer, String> studentMap = new LinkedHashMap<Integer, String>(); to Map<Integer, String> studentMap = new LinkedHashMap<>();
从linkedhashmap删除条目
有两种方法可以在LinkedHashMap中删除条目。
remove(Object key):它从LinkedHashMap删除密钥remove(Object key,Object value):如果值与传递参数值相同,则会删除键。
package org.igi.theitroad.HashMap;
package org.igi.theitroad;
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapRemoveMain {
public static void main(String[] args) {
Map<String, Integer> travelFareMap = new LinkedHashMap<String, Integer>();
//Putting key-values pairs in LinkedHashMap
travelFareMap.put("Bus", 120);
travelFareMap.put("Car", 2200);
travelFareMap.put("Rail", 680);
travelFareMap.put("Flight", 4000);
System.out.println(travelFareMap);
//Remove car key
Integer fareCar = travelFareMap.remove("Car");
System.out.println("===============================");
System.out.println("Vehicle Car with fare "+fareCar+" removed from HashMap");
System.out.println(travelFareMap);
System.out.println("================================");
//Remove Rail if fate is 800
boolean isCarRemoved = travelFareMap.remove("Rail",800);
//Rail key won't be removed as associated value is 680
System.out.println("Did car removed from LinkedHashMap: "+isCarRemoved);
System.out.println(travelFareMap);
System.out.println("===============================");
//Remove Flight if fare is 4000
boolean isFlightRemoved = travelFareMap.remove("Flight",4000);
//flight key will be removed as associated value is 4000
System.out.println("Did Flight removed from LinkedHashMap: "+isFlightRemoved);
System.out.println(travelFareMap);
System.out.println("===============================");
}
}
重要的是LinkedHashMap方法
get():从LinkedHashMap检索值put():将值放入LinkedHashMapisEmpty:检查linkedhashmap是否为空。containsKey():检查键存在是否是LinkedHashMapcontainsValue():检查LinkedHashMap中是否存在值size():检查LinkedHashMap的大小clear():删除来自linkedhashmap的所有元素clone():它创建了LinkedHashMap的浅副本。
以下是涵盖这些方法的示例。
package org.igi.theitroad;
import java.util.LinkedHashMap;
import java.util.Map;
public class LinkedHashMapMethodsMain {
public static void main(String[] args) {
Map<String, String> profDeptmap = new LinkedHashMap<>();
//check if map is empty
boolean empty = profDeptmap.isEmpty();
System.out.println("is profDeptmap empty: "+empty);
//Putting key-values pairs in HashMap
profDeptmap.put("Arvind","Chemistry");
profDeptmap.put("Venkat", "Physics");
profDeptmap.put("Mary", "History");
profDeptmap.put("David","Maths");
System.out.println(profDeptmap);
//check size of map
System.out.println("size of profDeptmap: "+profDeptmap.size());
//get value from LinkedHashMap
System.out.println("Venkat's department: "+profDeptmap.get("Venkat"));
//Hamlet department will be null as we don't have key as "Hamlet"
System.out.println("Hamlet's department: "+profDeptmap.get("Hamlet"));
if(profDeptmap.containsKey("David"))
{
System.out.println("profDeptmap has David as key");
}
if(profDeptmap.containsValue("History"))
{
System.out.println("profDeptmap has History as value");
}
//Removing all entries from Map
profDeptmap.clear();
System.out.println(profDeptmap);
}
}
输出:
profdeptmap fight:true {arvind = chemistry,venkat =物理,mary = history,david = maths} profdeptmap的大小:4 Venkat部门:物理哈姆雷特部门:null profdeptmap有大卫,因为关键profdeptmap有历史{}}
获取LinkedHashMap的RestSet(),keyset()和值()
entryset()
entrySet():哈希图以形式存储关键值对Entry,我们可以通过调用来检索entryset()map.entrySet()
keyset()
keySet():提供一组密钥。
values()
values():提供一个值的集合。
这是一个例子。
package org.igi.theitroad;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class LinkedHashMapMain {
public static void main(String[] args) {
Map<Integer, String> studentIDNameMap = new LinkedHashMap<>();
//Putting key-values pairs in LinkedHashMap
studentIDNameMap.put(1001,"Andrew");
studentIDNameMap.put(1002, "Martin");
studentIDNameMap.put(1003, "Sameer");
studentIDNameMap.put(1004,"Venkat");
//get entrySet
Set<Entry<Integer, String>> entrySet = studentIDNameMap.entrySet();
System.out.println("EntrySet: "+entrySet);
//get keySet
Set<Integer> keySet = studentIDNameMap.keySet();
System.out.println("keySet: "+keySet);
//get values
Collection<String> values = studentIDNameMap.values();
System.out.println("values: "+values);
}
}
迭代linkedhashmap.
有很多方法可以迭代linkedhashmap
- 使用LinkedHashMap迭代
keyset() - 使用LinkedHashMap迭代
keyset()使用foreach()和lambda表达式(Java 8) - 使用foreach()和lambda表达式迭代LinkedHashMap(Java 8)
- 迭代LinkedHashMap的
entrySet()使用iterator - 迭代LinkedHashMap的
entrySet()使用foreach()和lambda表达式[Java 8] - 迭代LinkedHashMap的
entrySet()使用foreach循环
package org.igi.theitroad;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
public class LinkedHashMapIterationMain {
public static void main(String[] args) {
Map<String, Long> countryPopulationMap = new LinkedHashMap<>();
//Putting key-values pairs in LinkedHashMap
countryPopulationMap.put("Netherlands",13000L);
countryPopulationMap.put("China", 15000L);
countryPopulationMap.put("Germany", 9000L);
countryPopulationMap.put("France",7000L);
System.out.println("=========================================================");
System.out.println("Iterating over LinkedHashMap with foreach and lambda:");
countryPopulationMap.forEach((country,population) -> {
System.out.println(country+" --> "+population);
}
);
System.out.println("=========================================================");
System.out.println("Iterating over LinkedHashMap using keyset() with foreach loop:");
for(String user:countryPopulationMap.keySet())
{
System.out.println(user+" --> "+countryPopulationMap.get(user));
}
System.out.println("=========================================================");
System.out.println("Iterating over LinkedHashMap keyset() with foreach and lambda:");
countryPopulationMap.keySet().forEach((user) -> {
System.out.println(user+" --> "+countryPopulationMap.get(user));
}
);
System.out.println("=========================================================");
System.out.println("Iterating over LinkedHashMap entrySet with iterator");
Iterator<Entry<String, Long>> iterator = countryPopulationMap.entrySet().iterator();
while(iterator.hasNext())
{
Entry<String, Long> next = iterator.next();
System.out.println(next.getKey()+" --> "+next.getValue());
}
System.out.println("=========================================================");
System.out.println("Iterating over LinkedHashMap's entrySet with foreach and lambda");
countryPopulationMap.entrySet().forEach((entry) -> {
System.out.println(entry.getKey()+" --> "+entry.getValue());
}
);
System.out.println("=========================================================");
System.out.println("Iterating over LinkedHashMap's entrySet with foreach loop");
for(Map.Entry<String, Long> entry:countryPopulationMap.entrySet())
{
System.out.println(entry.getKey()+" --> "+entry.getValue());
}
}
}
访问订单linkedhashmap.
如果要从访问顺序中从LinkedHashMap检索条目,则可以使用 LinkedHashMap(int initialCapacity, float loadFactor, boolean accessOrder)构造函数。
让我为我们提供具有访问订单的LinkedHashMap的实时Usecase。
我们可以使用LinkedHashMap与访问顺序来实现LRU缓存。
创建一个名为的类 LRULHCache
package org.igi.theitroad;
import java.util.LinkedHashMap;
import java.util.Map;
class LRULHCache<K,V> {
private LinkedHashMap<K, V> map;
public LRULHCache(int capacity)
{
map = new LinkedHashMap<K, V>(capacity, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry eldest)
{
return size() > capacity;
}
};
}
//This method works in O(1)
public V get(K key)
{
return map.get(key);
}
//This method works in O(1)
public void set(K key, V value)
{
map.put(key, value);
}
@Override
public String toString() {
return "LinkedHashMap: "+map.toString();
}
}
public class LinkedHashMapAccessOrderMain {
public static void main(String[] args)
{
LRULHCache<Integer,Integer> lruLHCache = new LRULHCache<>(2);
lruLHCache.set(2, 12000);
lruLHCache.set(40, 70000);
System.out.println(lruLHCache);
//renews the entry
System.out.println(lruLHCache.get(2));
System.out.println(lruLHCache);
lruLHCache.set(20, 70000);
System.out.println(lruLHCache);
System.out.println(lruLHCache.get(2));
System.out.println(lruLHCache);
System.out.println(lruLHCache.get(40));
}
}
输出
LinkedHashMap: {2=12000, 40=70000}
12000
LinkedHashMap: {40=70000, 2=12000}
LinkedHashMap: {2=12000, 20=70000}
12000
LinkedHashMap: {20=70000, 2=12000}
null
正如我们所看到的那样,我们已经使用容量2创建了Lrulhcache,一旦我们调用 get(),LinkedHashMap正在使用该密钥续订。
是LinkedHashMap线程安全吗?
LinkedHashMap默认情况下不是线程安全,在多线程环境的情况下,它可以给出非确定性结果。
如果多个线程尝试访问LinkedHashMap,其中一个是结构修改,那么它应该外部同步。
在LinkedHashMap创建时间在LinkedHashMap执行此操作的最佳方式。
Map m=Collections.synchronizedMap(new LinkedHashMap());

