LinkedHashMap in Java

The LinkedHashMap is just like HashMap with an additional feature of maintaining an order of elements inserted into it. HashMap provided the advantage of quick insertion, search, and deletion but it never maintained the track and order of insertion which the LinkedHashMap provides where the elements can be accessed in their insertion order. 

Important Features of a LinkedHashMap:

  • A LinkedHashMap contains values based on the key. It implements the Map interface and extends the HashMap class.
  • It contains only unique elements.
  • It may have one null key and multiple null values.
  • It is non-synchronized.
  • It is the same as HashMap with an additional feature that it maintains insertion order. For example, when we run the code with a HashMap, we get a different order of elements.

Declaration:

public class LinkedHashMap<K,​V> extends HashMap<K,​V> implements Map<K,​V>

Here, K is the key Object type and V is the value Object type.

The Hierarchy of LinkedHashMap



LinkedHashMap in Java

It implements Map<K, V> interface, and extends HashMap<K, V> class.

Constructors of LinkedHashMap

To create a LinkedHashMap, we need to create an object of the LinkedHashMap class. The LinkedHashMap class consists of various constructors that allow the possible creation of the ArrayList. The following are the constructors available in this class:

1. LinkedHashMap(): This is used to construct a default LinkedHashMap constructor.

LinkedHashMap<K, V> lhm = new LinkedHashMap<K, V>();

2. LinkedHashMap(int capacity): It is used to initialize a particular LinkedHashMap with a specified capacity.

LinkedHashMap<K, V> lhm = new LinkedHashMap<K, V>(int capacity);

3. LinkedHashMap(Map<? extends K,​? extends V> map): It is used to initialize a particular LinkedHashMap with the elements of the specified map.



LinkedHashMap<K, V> lhm = new LinkedHashMap<K, V>(Map<? extends K,​? extends V> map);

4. LinkedHashMap(int capacity, float fillRatio): It is used to initialize both the capacity and fill ratio for a LinkedHashMap. A fillRatio also called as loadFactor is a metric that determines when to increase the size of the LinkedHashMap automatically. By default, this value is 0.75 which means that the size of the map is increased when the map is 75% full.

LinkedHashMap<K, V> lhm = new LinkedHashMap<K, V>(int capacity, float fillRatio);

5. LinkedHashMap(int capacity, float fillRatio, boolean Order): This constructor is also used to initialize both the capacity and fill ratio for a LinkedHashMap along with whether to follow the insertion order or not.

LinkedHashMap<K, V> lhm = new LinkedHashMap<K, V>(int capacity, float fillRatio, boolean Order);

Here, For Order attribute, true is passed for last access order and false is passed for insertion order.

Example: The following implementation demonstrates how to create and use a LinkedHashMap.
 

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to demonstrate working of LinkedHashMap
  
import java.util.*;
  
public class LinkedHashMapExample {
    
    public static void main(String a[])
    {
        // create an instance of LinkedHashMap
        LinkedHashMap<String, String> lhm
            = new LinkedHashMap<String, String>();
  
        // Add mappings using put method
        lhm.put("one", "practice.geeksforgeeks.org");
        lhm.put("two", "code.geeksforgeeks.org");
        lhm.put("four", "quiz.geeksforgeeks.org");
  
        // It prints the elements in same order
        // as they were inserted
        System.out.println(lhm);
  
        System.out.println("Getting value for key 'one': "
                           + lhm.get("one"));
  
        System.out.println("Size of the map: "
                           + lhm.size());
  
        System.out.println("Is map empty? "
                           + lhm.isEmpty());
  
        System.out.println("Contains key 'two'? "
                           + lhm.containsKey("two"));
  
        System.out.println(
            "Contains value 'practice.geeks"
            + "forgeeks.org'? "
            + lhm.containsValue("practice"
                                + ".geeksforgeeks.org"));
  
        System.out.println("delete element 'one': "
                           + lhm.remove("one"));
  
        // print mappings to the console
        System.out.println("Mappings of LinkedHashMap : "
                           + lhm);
    }
}

chevron_right


Output

{one=practice.geeksforgeeks.org, two=code.geeksforgeeks.org, four=quiz.geeksforgeeks.org}
Getting value for key 'one': practice.geeksforgeeks.org
Size of the map: 3
Is map empty? false
Contains key 'two'? true
Contains value 'practice.geeksforgeeks.org'? true
delete element 'one': practice.geeksforgeeks.org
Mappings of LinkedHashMap : {two=code.geeksforgeeks.org, four=quiz.geeksforgeeks.org}

Performing various operations on the HashMap class

Let’s see how to perform a few frequently used operations on the LinkedHashMap.

1. Adding Elements: In order to add an element to the LinkedHashMap, we can use the put() method. This is different from HashMap because in HashMap, the insertion order is not retained but it is retained in the LinkedHashMap. 



Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to demonstrate adding
// elements to a LinkedHashMap
  
import java.util.*;
  
class AddElementsToLinkedHashMap {
  
    public static void main(String args[])
    {
  
        // Initialization of a LinkedHashMap
        // using Generics
        LinkedHashMap<Integer, String> hm1
            = new LinkedHashMap<Integer, String>();
  
        // Add mappings using
        // put() method
        hm1.put(3, "Geeks");
        hm1.put(2, "For");
        hm1.put(1, "Geeks");
  
        // print mappings to the console
        System.out.println("Mappings of LinkedHashMap : "
                           + hm1);
    }
}

chevron_right


Output

Mappings of LinkedHashMap : {3=Geeks, 2=For, 1=Geeks}

2. Changing Elements: After adding the elements if we wish to change the element, it can be done by again adding the element with the put() method. Since the elements in the treemap are indexed using the keys, the value of the key can be changed by simply inserting the updated value for the key for which we wish to change.
 

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to demonstrate
// changing/updating of LinkedHashMap
  
import java.util.*;
  
class UpdatingLinkedHashMap {
  
    public static void main(String args[])
    {
        // Initialization of a LinkedHashMap
        // using Generics
        LinkedHashMap<Integer, String> hm
            = new LinkedHashMap<Integer, String>();
  
        // Insert mappings using put() method
        hm.put(3, "Geeks");
        hm.put(2, "Geeks");
        hm.put(1, "Geeks");
  
        // print mappings to the console
        System.out.println("Initial map : " + hm);
  
        // Update the value with key 2
        hm.put(2, "For");
  
        // print the updated map
        System.out.println("Updated Map : " + hm);
    }
}

chevron_right


Output

Initial map : {3=Geeks, 2=Geeks, 1=Geeks}
Updated Map : {3=Geeks, 2=For, 1=Geeks}

3. Removing Element: In order to remove an element from the TreeMap, we can use the remove() method. This method takes the key value and removes the mapping for the key from this treemap if it is present in the map. Apart from that, we can also remove the first entered element from the map if the maximum size is defined as discussed in this article
 

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to demonstrate the
// removing of elements from LinkedHashMap
  
import java.util.*;
  
class RemovingMappingsFromLinkedHashMap {
    public static void main(String args[])
    {
        // Initialization of a LinkedHashMap
        // using Generics
        LinkedHashMap<Integer, String> hm
            = new LinkedHashMap<Integer, String>();
  
        // Inserting the Elements
        // using put() method
        hm.put(3, "Geeks");
        hm.put(2, "Geeks");
        hm.put(1, "Geeks");
        hm.put(4, "For");
  
        // print the mappings to the console
        System.out.println("Initial Map : " + hm);
  
        // Remove the mapping with Key 4
        hm.remove(4);
  
        // print the updated map
        System.out.println("Updated Map : " + hm);
    }
}

chevron_right


Output

Initial Map : {3=Geeks, 2=Geeks, 1=Geeks, 4=For}
Updated Map : {3=Geeks, 2=Geeks, 1=Geeks}

4. Iterating through the LinkedHashMap: There are multiple ways to iterate through the Map. The most famous way is to use a for-each loop and get the keys. The value of the key is found by using the getValue() method.
 

Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to demonstrate
// iterating over LinkedHashMap
  
import java.util.*;
class IteratingOverLinkedHashMap {
    public static void main(String args[])
    {
        // Initialization of a LinkedHashMap
        // using Generics
        LinkedHashMap<Integer, String> hm
            = new LinkedHashMap<Integer, String>();
  
        // Inserting the Elements
        hm.put(3, "Geeks");
        hm.put(2, "For");
        hm.put(1, "Geeks");
  
        for (Map.Entry<Integer, String> mapElement : hm.entrySet()) {
  
            Integer key = mapElement.getKey();
  
            // Finding the value
            String value = mapElement.getValue();
  
            // print the key : value pair
            System.out.println(key + " : " + value);
        }
    }
}

chevron_right


Output

3 : Geeks
2 : For
1 : Geeks

How LinkedHashMap work internally?

A LinkedHashMap is an extension of the HashMap class and it implements the Map interface. Therefore, the class is declared as:
 

public class LinkedHashMap extends HashMap implements Map 
 

In this class, the data is stored in the form of nodes. The implementation of the LinkedHashMap is very similar to a doubly-linked list. Therefore, each node of the LinkedHashMap is represented as:
 



LinkedHashMap-Node-in-Java

 

  • Hash: All the input keys are converted into a hash which is a shorter form of the key so that the search and insertion are faster.
  • Key: Since this class extends HashMap, the data is stored in the form of a key-value pair. Therefore, this parameter is the key to the data.
  • Value: For every key, there is a value associated with it. This parameter stores the value of the keys. Due to generics, this value can be of any form.
  • Next: Since the LinkedHashMap stores the insertion order, this contains the address to the next node of the LinkedHashMap.
  • Previous: This parameter contains the address to the previous node of the LinkedHashMap.
     

Synchronized LinkedHashMap

The implementation of LinkedHashMap not synchronized. If multiple threads access a linked hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be “wrapped” using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map:

  Map m = Collections.synchronizedMap(new LinkedHashMap(…));

Methods of LinkedHashMap 

  • K – The type of the keys in the map.
  • V – The type of values mapped in the map.

METHOD

DESCRIPTION

containsValue​(Object value) Returns true if this map maps one or more keys to the specified value.
entrySet() Returns a Set view of the mappings contained in this map.
get​(Object key) Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
keySet() Returns a Set view of the keys contained in this map.
removeEldestEntry​(Map.Entry<K,​V> eldest) Returns true if this map should remove its eldest entry.
values() Returns a Collection view of the values contained in this map.

Methods declared in class java.util.HashMap

METHOD

DESCRIPTION

clear() Removes all of the mappings from this map.
clone() Returns a shallow copy of this HashMap instance: the keys and values themselves are not cloned.
compute​(K key, BiFunction<? super K,​? super V,​? extends V> remappingFunction) Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).
computeIfAbsent​(K key, Function<? super K,​? extends V> mappingFunction) If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.
computeIfPresent​(K key, BiFunction<? super K,​? super V,​? extends V> remappingFunction) If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value.
containsKey​(Object key) Returns true if this map contains a mapping for the specified key.
containsValue​(Object value) Returns true if this map maps one or more keys to the specified value.
entrySet() Returns a Set view of the mappings contained in this map.
get​(Object key) Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key.
isEmpty() Returns true if this map contains no key-value mappings.
keySet() Returns a Set view of the keys contained in this map.
merge​(K key, V value, BiFunction<? super V,​? super V,​? extends V> remappingFunction) If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value.
put​(K key, V value) Associates the specified value with the specified key in this map.
putAll​(Map<? extends K,​? extends V> m) Copies all of the mappings from the specified map to this map.
remove​(Object key) Removes the mapping for the specified key from this map if present.
size() Returns the number of key-value mappings in this map.
values() Returns a Collection view of the values contained in this map.

Methods declared in class java.util.AbstractMap

METHOD



DESCRIPTION

equals​(Object o) Compares the specified object with this map for equality.
hashCode() Returns the hash code value for this map.
toString() Returns a string representation of this map.

Methods declared in interface java.util.Map

METHOD

DESCRIPTION

 clear() Removes all of the mappings from this map (optional operation).
compute​(K key, BiFunction<? super K,​? super V,​? extends V> remappingFunction) Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping).
computeIfAbsent​(K key, Function<? super K,​? extends V> mappingFunction) If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.
computeIfPresent​(K key, BiFunction<? super K,​? super V,​? extends V> remappingFunction) If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value.
containsKey​(Object key) Returns true if this map contains a mapping for the specified key.
equals​(Object o) Compares the specified object with this map for equality.
forEach​(BiConsumer<? super K,​? super V> action) Performs the given action for each entry in this map until all entries have been processed or the action throws an exception.
getOrDefault​(Object key, V defaultValue) Returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key.
hashCode() Returns the hash code value for this map.
isEmpty() Returns true if this map contains no key-value mappings.
merge​(K key, V value, BiFunction<? super V,​? super V,​? extends V> remappingFunction) If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value.
put​(K key, V value) Associates the specified value with the specified key in this map (optional operation).
putAll​(Map<? extends K,​? extends V> m) Copies all of the mappings from the specified map to this map (optional operation).
putIfAbsent​(K key, V value) If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value.
remove​(Object key) Removes the mapping for a key from this map if it is present (optional operation).
remove​(Object key, Object value) Removes the entry for the specified key only if it is currently mapped to the specified value.
replace​(K key, V value) Replaces the entry for the specified key only if it is currently mapped to some value.
replace​(K key, V oldValue, V newValue) Replaces the entry for the specified key only if currently mapped to the specified value.
replaceAll​(BiFunction<? super K,​? super V,​? extends V> function) Replaces each entry’s value with the result of invoking the given function on that entry until all entries have been processed or the function throws an exception.
size() Returns the number of key-value mappings in this map.

Application: Since the LinkedHashMap makes use of Doubly LinkedList to maintain the insertion order, we can implement LRU Cache functionality by overriding the removeEldestEntry() method to impose a policy for automatically removing stale when new mappings are added to the map. This lets you expire data using some criteria that you define.

Reference: https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/LinkedHashMap.html

Related Articles:

Attention reader! Don’t stop learning now. Get hold of all the important Java and Collections concepts with the Fundamentals of Java and Java Collections Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up