在Java中的LinkedHashMap
LinkedHashMap是一个散列和链接的基于列表的Map接口实现,具有可预测的插入顺序。
它保持所有条目的双链接列表,这就是它与HashMap的不同之处。
java linkedhashmap.
关于LinkedHashMap的一些说明
- LinkedHashMap实现映射接口并扩展HashMap类。
- LinkedHashMap维护插入顺序,因此当我们能够按顺序访问元素时,它们会像ArrayList一样访问。
- LinkedHashMap维护双链接列表以维护插入顺序。
- 它不同步,并且不是线程安全的。
- 不允许重复键
- 一个
null
key和多个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());