Java Map Interface Examples

Recently I was explaining someone about Java Map and various implementations that are available as part of JDK.

I had wrote a simple program to explain him that. Thought of putting it here. Below it is –

TreeMap – The map is sorted according to the natural ordering of its keys, or by a Comparator provided at map creation time, depending on which constructor is used. Below example you will notice that treeMap toString shows that entries are ordered by performing natural ordering on Int keys.

HashMap – This class makes no guarantees as to the order of the map. Uses object equality to check if key already exist in map and replace value if it exist. As in example while trying to put key11 as it equals with key1 value “One” is replaced with “Eleven”.

IdentityHashMap - Unlike above HashMap, this uses reference-equality in place of object-equality when comparing keys. As in following example even after key11 equals key1, but as their references are not equals so a new key/value is inserted.

LinkedHashMap – This implementation keeps track of order in which keys were inserted into the map. In below example you will notice that the toString shows entries in same order in which they were inserted. This also has another feature discussed next.

LRU Caching using LinkedHashMap – Another feature of LinkedHashMap is that it provide constructor to create a linked hash map whose order of iteration is the order in which its entries were last accessed, from least-recently accessed to most-recently (access-order). In following example, you will notice that when elements are inserted and none is accessed yet, the order of Entries is same as that of above example. But after accessing elements, you will notice that the entries order is changed based on when last it was accessed. Using this feature one can create a LRU(accessed) cache as shown in example. You will need to override removeEldestEntry method of LinkedHashMap and add your logic for caching. Each put operation will call this removeEldestEntry by passing least-recently-accessed element to it and based on removeEldestEntry’s return value it will either be kept or removed from the map.

WeakHashMap- In this implementation keys are held as WeakReferences. This way if there is no strong reference for key, on next Garbage Collection this key and corresponding value will be removed from the Map. Read this article for details on Java References. As in below example we are adding three keys to map and then clearing one strong reference to key6 by setting it to null. Then we request GC by calling System.gc() and in next statement you will notice that the key/value for key6 is removed from Map.

package collections;

import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.WeakHashMap;

public class DemoMap {

    public static void main(String[] args) {
        // TreeMap
        Map<Integer, String> treeMap = new TreeMap<Integer, String>();
        treeMap.put(4, "Four");
        treeMap.put(1, "One");
        treeMap.put(5, "Five");
        treeMap.put(3, "Three");
        treeMap.put(2, "Two");
        System.out.println("TreeMap - " + treeMap);
        // TreeMap - {1=One, 2=Two, 3=Three, 4=Four, 5=Five}

        // HashMap
        Key key1 = new Key(1);
        Key key11 = new Key(1);
        Key key2 = new Key(2);
        Key key3 = new Key(3);
        Map<Key, String> map = new HashMap<Key, String>();
        map.put(key1, "One");
        map.put(key11, "Eleven");
        map.put(key2, "Two");
        map.put(key3, "Three");
        System.out.println("HashMap - " + map);
        // HashMap - {3=Three, 1=Eleven, 2=Two}

        // IdentityHashMap
        Map<Key, String> idMap = new IdentityHashMap<Key, String>();
        idMap.put(key1, "One");
        idMap.put(key11, "One");
        idMap.put(key2, "Two");
        idMap.put(key3, "Three");
        System.out.println("IdentityHashMap - " + idMap);
        // IdentityHashMap - {1=One, 1=One, 3=Three, 2=Two}

        // LinkedHashMap
        Map<Integer, String> linkedMap = new LinkedHashMap<Integer, String>(5);
        linkedMap.put(4, "Four");
        linkedMap.put(1, "One");
        linkedMap.put(5, "Five");
        linkedMap.put(3, "Three");
        linkedMap.put(2, "Two");
        System.out.println("LinkedHashMap - " + linkedMap);
        //LinkedHashMap - {4=Four, 1=One, 5=Five, 3=Three, 2=Two}
        
        // LinkedHashMap for Caching using access-order
        Map<Integer, String> cachedLinkedMap = new CacheUsingLinkedHashMap<Integer, String>(5);
        cachedLinkedMap.put(4, "Four");
        cachedLinkedMap.put(1, "One");
        cachedLinkedMap.put(5, "Five");
        cachedLinkedMap.put(3, "Three");
        cachedLinkedMap.put(2, "Two");
        System.out.println("LinkedHashMap at full capacity no access performed yet - " + cachedLinkedMap);
        // LinkedHashMap at full capacity no access performed yet - {4=Four, 1=One, 5=Five, 3=Three, 2=Two}
        cachedLinkedMap.get(1);
        cachedLinkedMap.get(2);
        cachedLinkedMap.get(4);
        cachedLinkedMap.get(5);
        cachedLinkedMap.get(3);
        System.out.println("LinkedHashMap at full capacity after accessing few elements - " + cachedLinkedMap);
        // LinkedHashMap at full capacity after accessing few elements - {1=One, 2=Two, 4=Four, 5=Five, 3=Three}
        cachedLinkedMap.put(6, "Six");
        System.out.println("LinkedHashMap after adding new entry - " + cachedLinkedMap);
        // As 1 is least recently accessed.
        // LinkedHashMap after adding new entry - {2=Two, 4=Four, 5=Five, 3=Three, 6=Six}

        // WeakHashMap
        Map<Key, String> weakMap = new WeakHashMap<Key, String>();
        Key key4 = new Key(4);
        Key key5 = new Key(5);
        Key key6 = new Key(6);
        weakMap.put(key4, "Four");
        weakMap.put(key5, "Five");
        weakMap.put(key6, "Six");
        System.out.println("WeakHashMap before GC - " + weakMap);
        // WeakHashMap before GC - {6=Six, 5=Five, 4=Four}
        key6 = null;
        System.gc();
        System.out.println("WeakHashMap after GC - " + weakMap);
        // WeakHashMap after GC - {5=Five, 4=Four}
    }

    static class CacheUsingLinkedHashMap<K, V> extends LinkedHashMap<K, V> {

        int capacity;

        public CacheUsingLinkedHashMap(int cap) {
            super(cap + 1, 1.1f, true);
            capacity = cap;
        }

        @Override
        protected boolean removeEldestEntry(java.util.Map.Entry<K, V> eldest) {
            return size() > capacity;
        }

    }

    static class Key {
        int key;

        public Key(int key) {
            this.key = key;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + key;
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Key other = (Key) obj;
            if (key != other.key)
                return false;
            return true;
        }

        @Override
        public String toString() {
            return String.valueOf(key);
        }
    }

}



Comments

  1. krunalNo Gravatar March 14th

    Comment Arrow

    This is very helpful. Thank you Shiva.

    Krunal


Add Yours

  • Author Avatar

    YOU


Comment Arrow




About Author

shiv

This author has not yet written a description. Please give them some time to get acquainted with the site and surely they will write their masterpiece.