Table of contents
1.
Introduction
2.
Hashtable
3.
Stack
4.
Dictionary
5.
Properties
6.
Vector
7.
Enumeration interface
8.
Difference between HashMap and Hashtable
9.
Frequently Asked Questions
9.1.
Can Hashtable be used in place of HashMap?
9.2.
Is Vector more efficient than ArrayList?
9.3.
Can the Enumeration interface be used with modern collection classes?
10.
Conclusion
Last Updated: Nov 12, 2024
Easy

Legacy Class in Java

Author Ravi Khorwal
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

In Java, various classes and interfaces have been part of the language since its early versions. These are known as legacy classes and interfaces. While some of them are still widely used, others have been replaced by more modern and efficient alternatives. Among these, legacy classes still hold a unique place as they were part of the original Java release, but they are still relevant and frequently used. 

Legacy Class in Java

In this article, we will discuss some of the most commonly used legacy classes and interfaces in Java, which are Hashtable, Stack, Dictionary, Properties, Vector, and the Enumeration interface. We'll also discuss the differences between HashMap & Hashtable. 

Hashtable

A Hashtable is a legacy class in Java that stores key-value pairs, which is similar to a HashMap. It uses a hash table data structure to store the elements, which allows fast retrieval of values based on their keys. 

For example : 

import java.util.Hashtable;

public class HashtableExample {
    public static void main(String[] args) {
        Hashtable<String, Integer> hashtable = new Hashtable<>();
        
        // Adding elements to the Hashtable
        hashtable.put("Ravi", 25);
        hashtable.put("Sinki", 30);
        hashtable.put("Gaurav", 35);
        
        // Retrieving values from the Hashtable
        int RaviAge = hashtable.get("Ravi");
        System.out.println("Ravi's age: " + RaviAge);
        
        // Removing an element from the Hashtable
        hashtable.remove("Sinki");
        
        // Checking if a key exists in the Hashtable
        boolean containsGaurav = hashtable.containsKey("Gaurav");
        System.out.println("Contains Gaurav: " + containsGaurav);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output

Ravi's age: 25
Contains Gaurav: true


In this example, we create a Hashtable that stores String keys and integer values. We add elements to the Hashtable using the `put()` method, retrieve values using the `get()` method, remove an element using the `remove()` method, and check if a key exists using the `containsKey()` method.

One important thing to note about Hashtable is that it is synchronized, which means that multiple threads can safely access it concurrently without the need for explicit synchronization. However, this synchronization comes with a performance overhead compared to unsynchronized classes like HashMap.

Stack

A Stack is a legacy class in Java that represents a last-in-first-out (LIFO) stack of elements. It extends the Vector class and provides additional operations specific to a stack, like push, pop, and peek. 

For example : 

import java.util.Stack;


public class StackExample {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<>();
        
        // Pushing elements onto the stack
        stack.push("Apple");
        stack.push("Banana");
        stack.push("Orange");
        
        // Peeking at the top element
        String topElement = stack.peek();
        System.out.println("Top element: " + topElement);
        
        // Popping elements from the stack
        String poppedElement = stack.pop();
        System.out.println("Popped element: " + poppedElement);
        
        // Checking if the stack is empty
        boolean isEmpty = stack.isEmpty();
        System.out.println("Is stack empty? " + isEmpty);
    }
}
You can also try this code with Online Java Compiler
Run Code


Output

Top element: Orange
Popped element: Orange
Is stack empty? false

 

In this example, we create a Stack of String elements. We push elements onto the stack using the `push()` method, which adds them to the top of the stack. We can peek at the top element without removing it using the `peek()` method. To remove and retrieve the top element from the stack, we use the `pop()` method. Finally, we can check if the stack is empty using the `isEmpty()` method.

The Stack class is synchronized, meaning it is thread-safe and can be accessed by multiple threads concurrently without the need for explicit synchronization.

However, it's important to remember that the Stack class is considered a legacy class. In most cases, it is strictly advised to use the Deque interface and its implementations, like ArrayDeque or LinkedList, which provide more flexibility and improved performance compared to the Stack class.

Dictionary

Dictionary is an abstract class in Java that represents a key-value mapping. It is a legacy class that has been largely replaced by the Map interface and its implementations, such as HashMap and TreeMap. The Dictionary class is obsolete and is not recommended for use in new code.

For example : 

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


public class DictionaryExample {
    public static void main(String[] args) {
        Dictionary<String, Integer> dictionary = new Hashtable<>();
        
        // Adding elements to the Dictionary
        dictionary.put("Ravi", 25);
        dictionary.put("Sinki", 30);
        dictionary.put("Gaurav", 35);
        
        // Retrieving values from the Dictionary
        int RaviAge = dictionary.get("Ravi");
        System.out.println("Ravi's age: " + RaviAge);
        
        // Removing an element from the Dictionary
        dictionary.remove("Sinki");
        
        // Checking if a key exists in the Dictionary
        boolean containsGaurav = dictionary.get("Gaurav") != null;
        System.out.println("Contains Gaurav: " + containsGaurav);
    }
}
You can also try this code with Online Java Compiler
Run Code

 

Output

Ravi's age: 25
Contains Gaurav: true


In this example, we create a Dictionary using the Hashtable class, one of the few concrete implementations of the Dictionary class. We add elements to the Dictionary using the `put()` method, retrieve values using the `get()` method, remove an element using the `remove()` method, and check if a key exists by comparing the result of `get()` with null.

However, as mentioned earlier, the Dictionary class is obsolete and has been replaced by the Map interface. The Map interface provides a more robust and flexible framework for working with key-value mappings. It offers various implementations, like HashMap, TreeMap, and LinkedHashMap, each with different characteristics and use cases.

Properties

Properties is a legacy class in Java that extends the Hashtable class and is used to store key-value pairs where both the key and value are strings. It provides methods to load and store properties from/to a file or an input/output stream. The Properties class is used for configuration settings and internationalization.

For example : 

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Properties;

public class PropertiesExample {
    public static void main(String[] args) {
        Properties properties = new Properties();
        
        // Setting properties
        properties.setProperty("database.url", "jdbc:mysql://localhost:3306/mydb");
        properties.setProperty("database.username", "root");
        properties.setProperty("database.password", "password");
        
        // Storing properties to a file
        try (FileOutputStream output = new FileOutputStream("config.properties")) {
            properties.store(output, "Database Configuration");
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // Loading properties from a file
        try (FileInputStream input = new FileInputStream("config.properties")) {
            properties.load(input);
            
            // Retrieving property values
            String url = properties.getProperty("database.url");
            String username = properties.getProperty("database.username");
            String password = properties.getProperty("database.password");
            
            System.out.println("URL: " + url);
            System.out.println("Username: " + username);
            System.out.println("Password: " + password);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output

URL: jdbc:mysql://localhost:3306/mydb
Username: root
Password: password


In this example, we create a Properties object and set some properties using the `setProperty()` method. We then store the properties in a file named "config.properties" using the `store()` method. Later, we load the properties from the same file using the `load()` method and retrieve the property values using the `getProperty()` method.
 

The Properties class provides a convenient way to store and retrieve configuration settings or localized messages in a key-value format. It supports loading properties from various sources, like files or input streams, and saving them back to files or output streams.

Vector

Vector is a legacy Java class that implements a dynamic array. It is similar to the ArrayList class but with a few differences. Vector is synchronized, meaning multiple threads can safely access it concurrently without explicit synchronization.

For example : 

import java.util.Vector;

public class VectorExample {
    public static void main(String[] args) {
        Vector<String> vector = new Vector<>();

        // Adding elements to the Vector
        vector.add("Apple");
        vector.add("Banana");
        vector.add("Orange");

        // Accessing elements by index
        String element = vector.get(1);
        System.out.println("Element at index 1: " + element);

        // Updating an element
        vector.set(2, "Grape");

        // Removing an element
        vector.remove(0);

        // Iterating over the Vector
        for (String fruit : vector) {
            System.out.println(fruit);
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output

Element at index 1: Banana
Banana
Grape


In this example, we create a Vector of String elements. We add elements to the Vector using the `add()` method. We can access elements by their index using the `get()` method & update elements using the `set()` method. To remove an element, we use the `remove()` method. We can also iterate over the Vector using a for-each loop.

Vector is thread-safe, which means that multiple threads can access it simultaneously without causing race conditions. However, this synchronization comes with a performance overhead compared to non-synchronized classes like ArrayList.

It's important to note that Vector is considered a legacy class. In most cases, it is recommended to use ArrayList or other collection classes from java.util package, as they offer better performance and more flexibility.


One unique feature of Vector is that it allows you to specify the capacity increment when creating the Vector. The capacity increment determines how much the Vector's capacity will increase when it needs to grow. You can specify the capacity increment in the constructor like this:

Vector<String> vector = new Vector<>(10, 5);


In this case, the vector's initial capacity is set to 10, and whenever it needs to grow, its capacity will increase by 5 elements.

Enumeration interface

The Enumeration interface is a legacy interface in Java that defines methods for enumerating (or iterating over) a collection of elements. It has been largely replaced by the Iterator interface, which provides a more flexible and standardized way of iterating over collections.

For example: 

import java.util.Enumeration;
import java.util.Vector;

public class EnumerationExample {
    public static void main(String[] args) {
        Vector<String> vector = new Vector<>();
        
        // Adding elements to the Vector
        vector.add("Apple");
        vector.add("Banana");
        vector.add("Orange");
        
        // Getting an Enumeration of the Vector
        Enumeration<String> enumeration = vector.elements();
        
        // Iterating over the elements using the Enumeration
        while (enumeration.hasMoreElements()) {
            String element = enumeration.nextElement();
            System.out.println(element);
        }
    }
}
You can also try this code with Online Java Compiler
Run Code


Output

Apple
Banana
Orange


In this example, we create a Vector of String elements and add some elements to it. To iterate over the elements using the Enumeration interface, we first obtain an Enumeration object by calling the `elements()` method on the Vector.
 

The Enumeration interface provides two main methods:

- `hasMoreElements()`: Returns true if there are more elements to be enumerated, false otherwise.
 

- `nextElement()`: Returns the next element in the enumeration. It throws a NoSuchElementException if there are no more elements.


We use a while loop to iterate over the elements using Enumeration. Inside the loop, we call `hasMoreElements()` to check if there are more elements to be enumerated. If there are, we call `nextElement()` to retrieve the next element and print it.

It's important to note that the Enumeration interface is considered a legacy interface and has been replaced by the Iterator interface in most cases. The Iterator interface provides additional methods like `remove()` and is more widely used in modern Java code.

However, some legacy classes, like Vector and Hashtable, still provide methods that return Enumeration objects for backward compatibility.

Difference between HashMap and Hashtable

HashMapHashtable
HashMap is non-synchronized, meaning multiple threads can access it simultaneously without built-in synchronization.Hashtable is synchronized, which means that multiple threads can safely access it concurrently without the need for explicit synchronization.
HashMap allows one null key and multiple null values.Hashtable does not allow null keys or values. Attempting to insert null will throw a NullPointerException.
HashMap is generally faster than Hashtable because it is not synchronized.Hashtable is slower compared to HashMap due to the overhead of synchronization.
HashMap is part of the Java Collections Framework and is commonly used in non-concurrent scenarios.Hashtable is a legacy class and is less commonly used in modern Java development.
HashMap does not guarantee the order of its elements.Hashtable also does not guarantee the order of its elements.
HashMap implements the Map interface.Hashtable implements the Map interface and extends the Dictionary class.
HashMap's iterators are fail-fast, meaning they will throw a ConcurrentModificationException if the map is modified while iterating.Hashtable's enumerations are not fail-fast and may not reflect concurrent modifications made to the table.
HashMap is preferred in most of the cases where thread safety is not required.Hashtable is helpful in situations where thread safety is necessary, but alternative concurrent collections like ConcurrentHashMap are generally recommended instead.

Frequently Asked Questions

Can Hashtable be used in place of HashMap?

While Hashtable can be used in place of HashMap, it is generally not recommended due to its synchronization overhead and legacy nature. HashMap is preferred for most use cases, unless thread safety is explicitly required.

Is Vector more efficient than ArrayList?

No, Vector is generally less efficient than ArrayList due to its synchronization overhead. ArrayList is preferred in most cases, unless thread safety is necessary.

Can the Enumeration interface be used with modern collection classes?

No, the Enumeration interface is a legacy interface and is not commonly used with modern collection classes. The Iterator interface is preferred for iterating over collections in modern Java development.

Conclusion

In this article, we have discussed many legacy classes and interfaces in Java, like Hashtable, Stack, Dictionary, Properties, Vector, and the Enumeration interface. We discussed their characteristics and usage with code examples. While these classes and interfaces have been part of Java since its early versions, many of them have been replaced by more modern and efficient alternatives in the Java Collections Framework. 

You can also check out our other blogs on Code360.

Live masterclass