在Java中的LinkedHashMap

时间:2020-02-23 14:35:26  来源:igfitidea点击:

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(<&gt;) to initialize Map.
You can change
Map<Integer, String&gt; studentMap = new LinkedHashMap<Integer, String&gt;();
to
Map<Integer, String&gt; studentMap = new LinkedHashMap<&gt;();

从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():将值放入LinkedHashMap
isEmpty:检查linkedhashmap是否为空。
containsKey():检查键存在是否是LinkedHashMap
containsValue():检查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());