Using a HashMap

A Map allows you to store elements, where each element is a key/value pair. Unlike an simple array where you store a value at a particular index, a Map determines the index itself and does this based on the hash value on the key. Eg. if you store a key key=”sinciput”, value=”the font part of the head or skull” in a Hashmap, the method hashcode (every Object inherits this method from the class Object) is invoked on “sinciput” which returns an integer that specifies where the key/value pair should go (internally, a HashMap uses an array):

   When writing: 
      HashMap hm = new HashMap();
      hm.put("sinciput", "the front part of the head or skull"); 
 
   hm internals:
      +----+
      |....|
      | 86 |    +------------------------------------------------------------+
      | 87 |--> | key="sinciput", value="the font part of the head or skull" |
      | 88 |    +------------------------------------------------------------+
      |....|
      +----+

If you store a key that already exists in the HashMap, it old key/value pair will be overwritten
Eg.

   When writing: 
      HashMap hm = new HashMap();
      hm.put("sinciput", "the front part of the head or skull"); 
      hm.put("sinciput", "dunno what it means");
 
   hm internals:
      +----+
      |....|
      | 86 |    +---------------------------------------------+
      | 87 |--> | key="sinciput", value="dunno what it means" |
      | 88 |    +---------------------------------------------+
      |....|
      +----+

If you store a key/value pair in which the hashcode of the keys maps to an index of the internal array that is already taken, the elements at that index acts as a linked list.
Eg.

   When writing:
      HashMap hm = new HashMap();
      hm.put("sinciput", "the front part");
      hm.put("whenever", "at any time");
 
   hm internals:
      +----+
      |....|
      | 86 |    +----------------------------------------+    +---------------------------+
      | 87 |--> | key="sinciput", value="the front part" |--> | "whenever", "at any time" |
      | 88 |    +----------------------------------------+    +---------------------------+
      |....|
      +----+

You can see that a HashMap (and HashTable) has the strong feature of doing lookups very quickly. Suppose you have built a HashMap of all dictionary words and you would like to know the meaning of “whenever”. You ask the HashMap if it contains that key and if so to return the value:

   if (hm.containsKey("whenever")) {
      Object value = hm.get("whenever");
   }

The method containsKey quickly determines that the index for “whenever” is 87 and then it just needs to sequentially look at each key in the linked list that appears on index 87. The get method does the same, but returns the value. Notice that get returns null when the key does not exist in the HashMap, but also returns null if the value of that key happens to be null. This is why you should use containsKey first if you know your HashMap is going to contain null values.

Internally a HashMap maintains an array. To have the HashMap work efficiently, the array must be large enough so that the key/value pairs are well-distributed and the performance is not affected. Therefore, the HashMap maintains two (customizable) variables capacity and loadFactor. The capacity is the length of the internal array and the loadFactor controls when the capacity should be increased.

Here’s an example:

import java.util.*;
import java.io.*;
    
public class Main 
{
   public static void main(String []args) throws Exception {
      String[] colors = { "black", "white", "blue", "green", 
                          "red", "yellow", "magenta", "cyan", 
                          "orange", "redorange",
                         "violet", "purple", "greenblue" };
      String[] rgbs = { "[0,0,0]", "[255,255,255]", "[0,0,255]", "[0,255,0]", 
                        "[255,0,0]", "[255,255,0]", "[255,0,255]", "[0,255,255]",
                        "[255,165,0]", "[255,69,0]", "[255,69,0]",
                        "[238,130,238]", "[160,32,240]", "[46,139,87]" };
 
      HashMap hm = new HashMap();
 
      for (int i=0; i<colors.length; i++) {
         hm.put(colors[i], rgbs[i]);
      }
 
 
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
      
      String line;
      System.out.print("Enter color ('exit' to exit): ");
      line = br.readLine();
      while (!line.equals("exit")) {
         if (hm.containsKey(line)) {
            System.out.println("t" + line + " is found with value " + hm.get(line));
         }
         else {
            System.out.println("t" + line + " is not found");
         }
         System.out.print("Enter color ('exit' to exit): ");
         line = br.readLine();
      }
   }
}

sample output:

C:>java Main
Enter color ('exit' to exit): red
        red is found with value [255,0,0]
Enter color ('exit' to exit): yellow
        yellow is found with value [255,255,0]
Enter color ('exit' to exit): green
        green is found with value [0,255,0]
Enter color ('exit' to exit): blue
        blue is found with value [0,0,255]
Enter color ('exit' to exit): violet
        violet is found with value [255,69,0]
Enter color ('exit' to exit): jefke
        jefke is not found
Enter color ('exit' to exit): exit