If you need to create a dictionary in a Java program, the most logical way to solve this problem is to use the dictionary data structure. This data structure allows you to store information in the form "key - value". Java has a special Dictionary class as well as its descendant, Hashtable. Also there is the Map interface and the HashMap class, which also stores “key - value” pairs. So there are many ways to create a Java dictionary.

Dictionary data structure

So, the Dictionary data structure stores information as a key-value combination. That is, with any value we associate a key (it can be, for example, id) and enter this pair into the dictionary. Addressing an element of the dictionary, deleting, searching in the dictionary is performed by the key. It seems convenient to organize using such data structure, for example, a telephone book, where the name (key) corresponds to the phone number (value).

Java Dictionary class and its extension

To begin with, java.util.Dictionary <K, V> util.Dictionary is an abstract class. It represents a key-value relation and works similar to a map. Given a key you can store values and when needed can retrieve the value back using its key. Thus, it is a list of key-value pair.

public abstract class Dictionary<K,V> extends Object
Since this class is abstract, we won’t work with it directly. Dictionary has a direct child class Hashtable. So for creating a dictionary in Java you can use Hashtable. This class implements a hash table, which maps keys to values and any non-null object can be used as a key or as a value. In Java hierarchy Hashtable extends Dictionary and implements Map. Let's give an example. We are going to create a classic dictionary, a telephone book, based on Hashtable.

Dictionary phoneBook = new Hashtable();
If we write this way, we should apply type casting for some operations. For example, for a key extraction.

System.out.println(((Hashtable) phoneBook).keySet());
To avoid this, we can change

Dictionary phoneBook = new Hashtable ();
on the

Hashtable phoneBook = new Hashtable ();
In our example, for clarity, we will leave the first option.

import java.util.Dictionary;
import java.util.Hashtable;

public class DictionaryDemo {

       public static void main(String[] args) {

           Dictionary phoneBook = new Hashtable();

           // put() method
           phoneBook.put("Johnny Walker", "2178");
           phoneBook.put("Andrew Arnold", "1298");
           phoneBook.put("Ivy Briggs", "1877");
           phoneBook.put("Ricky McBright", "2001");

           //print out Hashtable out
           System.out.println(phoneBook);

           //let's get the value using the key
           System.out.println(phoneBook.get("Ivy Briggs"));
           //there's no such key in out Hashtable
           System.out.println(phoneBook.get("Sol Frank"));

           //Is there a record with the "Johnny Walker" key?
           System.out.println(((Hashtable) phoneBook).containsKey("Johnny Walker"));
           //all keys of the Hashtable
           System.out.println(((Hashtable) phoneBook).keySet());
           //values from Hashtable
           System.out.println(((Hashtable) phoneBook).values());

           //the quantity of records
           System.out.println(phoneBook.size());
           //removing one record
           phoneBook.remove("Andrew Arnold");
           System.out.println(phoneBook);
       }
   }
The output is:
{Andrew Arnold=1298, Johnny Walker=2178, Ricky McBright=2001, Ivy Briggs=1877} 1877 null true [Andrew Arnold, Johnny Walker, Ricky McBright, Ivy Briggs] [1298, 2178, 2001, 1877] 4 {Johnny Walker=2178, Ricky McBright=2001, Ivy Briggs=1877}

HashMap as a dictionary

HashMap, unlike Hashtable, isn’t a direct descendant of Dictionary. However, due to many features, in most cases it is better to create a dictionary using HashMap. The HashMap class is very similar in functionality to Hashtable. The main difference is that the methods of the Hashtable are synchronized, but the HashMap are not. Synchronization in the Hashtable decreases the performance of code. In addition, the HashMap class, unlike Hashtable, allows the use of null as a key (one) and a set of null as values. In our case, the program will look exactly the same as the example above. The only difference is in the type of the collection. However, this is the preferred way to work with dictionaries in Java in most cases.

import java.util.HashMap;
import java.util.Map;

public class DictionaryDemo2 {

   public static void main(String[] args) {

       Map<String, String> phoneBook = new HashMap<String,String>();
      
       phoneBook.put("Johnny Walker", "2178");
       phoneBook.put("Andrew Arnold", "1298");
       phoneBook.put("Ivy Briggs", "1877");
       phoneBook.put("Ricky McBright", "2001");
      
       System.out.println(phoneBook);
      
       System.out.println(phoneBook.get("Johnny Walker"));
       System.out.println(phoneBook.get("Ivy Briggs"));
       System.out.println(phoneBook.get("Unknown Friend"));
      
       System.out.println(phoneBook.containsKey("Johnny Walker"));
       System.out.println(phoneBook.containsKey("Unknown Friend"));

       System.out.println(phoneBook.keySet());
       System.out.println(phoneBook.values());

       System.out.println(phoneBook.size());

       phoneBook.remove("Andrew Arnold");

       System.out.println(phoneBook);
   }

}
Here is the output:
{Andrew Arnold=1298, Ivy Briggs=1877, Ricky McBright=2001, Johnny Walker=2178} 2178 1877 null true false [Andrew Arnold, Ivy Briggs, Ricky McBright, Johnny Walker] [1298, 1877, 2001, 2178] 4 {Ivy Briggs=1877, Ricky McBright=2001, Johnny Walker=2178}

The Dictionary class in Java has been part of the language since its early versions, serving as a key-value storage mechanism. However, modern Java programming often discourages its use due to several limitations and the availability of better alternatives. This guide explores the obsolescence, limited functionality, and lack of type safety of the Dictionary class.

The Obsolescence of the Dictionary Class

The Dictionary class is considered obsolete in modern Java programming. While it was originally introduced as a part of the Java 1.0 release, it has largely been replaced by the Map interface and its implementations, such as HashMap and TreeMap. Reasons for its obsolescence include:

  • Lack of Updates: The Dictionary class has not been updated to include features introduced in later versions of Java.
  • Superseded by Map Interface: The Map interface provides a more modern and versatile approach to key-value storage.
  • Deprecated Style: The design of the Dictionary class is not consistent with the generic type system introduced in Java 5.

Limited Functionality of the Dictionary Class

The Dictionary class has several functional limitations compared to the Map interface and its implementations:

  • No Iteration Support: The Dictionary class lacks built-in support for iterating over its keys and values, making it less convenient to use.
  • No Null Keys or Values: Unlike HashMap, the Dictionary class does not allow null keys or values.
  • Limited API: The Dictionary class has a minimal set of methods, such as put(), get(), and remove(), whereas Map provides richer functionality, including key sets, value collections, and advanced operations.

Example of Dictionary API:


import java.util.Dictionary;
import java.util.Hashtable;

public class DictionaryExample {
    public static void main(String[] args) {
        Dictionary dictionary = new Hashtable<>();

        dictionary.put("key1", "value1");
        dictionary.put("key2", "value2");

        System.out.println("Value for key1: " + dictionary.get("key1"));
    }
}

While this example demonstrates basic usage, the limited API quickly becomes apparent when compared to Map.

Lack of Type Safety in the Dictionary Class

The Dictionary class does not support generics, leading to potential type safety issues. For example:


import java.util.Dictionary;
import java.util.Hashtable;

public class TypeSafetyExample {
    public static void main(String[] args) {
        Dictionary dictionary = new Hashtable(); // No type parameters

        dictionary.put("key1", "value1");
        dictionary.put(42, "value2"); // Allowed, but risky

        String value = (String) dictionary.get(42); // ClassCastException
    }
}

Output:

 Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String

To avoid these risks, modern Java programs should use the Map interface, which supports generics, ensuring type safety:

import java.util.Map;
import java.util.HashMap;

public class TypeSafeExample {
    public static void main(String[] args) {
        Map map = new HashMap<>();

        map.put("key1", "value1");
        map.put("key2", "value2");

        String value = map.get("key1");
        System.out.println("Value: " + value);
    }
}