Java Collections checkedMap() Method

The checkedMap() method in Java provides a way to create a dynamically typesafe view of a specified map. This ensures that only keys and values of the specified types can be added to the map, enhancing type safety and reducing the risk of runtime errors.

Table of Contents

  1. Introduction
  2. checkedMap() Method Syntax
  3. Examples
    • Basic Usage with Checked Map
    • Using Checked Map with Custom Classes
  4. Real-World Use Case
  5. Conclusion

Introduction

The Collections.checkedMap() method is part of the java.util.Collections class and is used to create a dynamically typesafe view of a specified map. This method enforces runtime type checking, ensuring that only keys and values of the specified types are allowed in the map. It helps prevent accidental insertion of incorrect types, providing a safeguard against ClassCastException at runtime.

This method is especially useful when working with legacy code or APIs that operate on raw types, as it helps maintain type integrity across different parts of the application.

checkedMap() Method Syntax

The syntax for the checkedMap() method is as follows:

public static <K, V> Map<K, V> checkedMap(Map<K, V> m, Class<K> keyType, Class<V> valueType)

Parameters:

  • m: The map for which a dynamically typesafe view is to be returned.
  • keyType: The type of keys that the map is permitted to hold.
  • valueType: The type of values that the map is permitted to hold.

Returns:

  • A dynamically typesafe view of the specified map.

Throws:

  • NullPointerException if the specified map, key type, or value type is null.

Examples

Basic Usage with Checked Map

The following example demonstrates how to use the checkedMap() method to enforce type safety in a map.

Example

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

public class CheckedMapExample {
    public static void main(String[] args) {
        // Create a raw map
        Map rawMap = new HashMap();
        
        // Create a checked map for String keys and Integer values
        Map<String, Integer> checkedMap = Collections.checkedMap(rawMap, String.class, Integer.class);

        // Adding elements of correct type
        checkedMap.put("One", 1);
        checkedMap.put("Two", 2);

        System.out.println("Checked Map: " + checkedMap);

        // Attempt to add a key-value pair of incorrect type
        try {
            Map raw = checkedMap;  // Temporarily treat the map as raw
            raw.put(3, "Three");  // Attempt to add an Integer key and String value
        } catch (ClassCastException e) {
            System.out.println("Error: Attempted to add an invalid type to the map");
        }
    }
}

Output:

Checked Map: {One=1, Two=2}
Error: Attempted to add an invalid type to the map

Using Checked Map with Custom Classes

You can also use the checkedMap() method with maps containing custom class instances to enforce type safety.

Example

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

class Student {
    String name;

    Student(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

class Course {
    String courseName;

    Course(String courseName) {
        this.courseName = courseName;
    }

    @Override
    public String toString() {
        return courseName;
    }
}

public class CustomCheckedMapExample {
    public static void main(String[] args) {
        Map<Student, Course> studentCourseMap = new HashMap<>();

        // Create a checked map for Student keys and Course values
        Map<Student, Course> checkedStudentCourseMap = Collections.checkedMap(studentCourseMap, Student.class, Course.class);

        // Add valid key-value pairs
        checkedStudentCourseMap.put(new Student("Amit"), new Course("Mathematics"));
        checkedStudentCourseMap.put(new Student("Neha"), new Course("Physics"));

        System.out.println("Student-Course Map: " + checkedStudentCourseMap);

        // Attempt to add a key-value pair of incorrect type
        try {
            Map raw = checkedStudentCourseMap;  // Temporarily treat the map as raw
            raw.put(new Student("Raj"), "Chemistry");  // Attempt to add a String value instead of Course
        } catch (ClassCastException e) {
            System.out.println("Error: Attempted to add an invalid type to the map");
        }
    }
}

Output:

Student-Course Map: {Amit=Mathematics, Neha=Physics}
Error: Attempted to add an invalid type to the map

Real-World Use Case

Ensuring Type Safety in API Integrations

In real-world applications, especially when integrating with legacy systems or libraries that use raw types, the checkedMap() method can enforce type constraints. This helps prevent runtime errors when maps are manipulated across different parts of an application or by different modules.

Example

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

class Employee {
    String name;
    int id;

    Employee(String name, int id) {
        this.name = name;
        this.id = id;
    }

    @Override
    public String toString() {
        return name + " (ID: " + id + ")";
    }
}

class Department {
    String departmentName;

    Department(String departmentName) {
        this.departmentName = departmentName;
    }

    @Override
    public String toString() {
        return departmentName;
    }
}

public class RealWorldUseCaseExample {
    public static void main(String[] args) {
        // A map that will be shared across modules
        Map<Employee, Department> employeeDepartmentMap = new HashMap<>();

        // Create a checked map for Employee keys and Department values
        Map<Employee, Department> checkedEmployeeDepartmentMap = Collections.checkedMap(employeeDepartmentMap, Employee.class, Department.class);

        // Module A adds employees and their departments
        checkedEmployeeDepartmentMap.put(new Employee("Raj", 101), new Department("HR"));
        checkedEmployeeDepartmentMap.put(new Employee("Simran", 102), new Department("Finance"));

        System.out.println("Employee-Department Map: " + checkedEmployeeDepartmentMap);

        // Module B, potentially written by another developer
        try {
            Map raw = checkedEmployeeDepartmentMap;  // Temporarily treat the map as raw
            raw.put(new Employee("Priya", 103), "Marketing");  // Attempt to add a String value instead of Department
        } catch (ClassCastException e) {
            System.out.println("Error: Attempted to add an invalid type to the map");
        }
    }
}

Output:

Employee-Department Map: {Raj (ID: 101)=HR, Simran (ID: 102)=Finance}
Error: Attempted to add an invalid type to the map

Conclusion

The Collections.checkedMap() method provides a valuable way to enforce type safety at runtime, helping prevent accidental insertion of incorrect types into maps. This is especially useful when dealing with raw types or integrating with legacy code. By utilizing checkedMap(), you can enhance the robustness and maintainability of your Java applications, ensuring that only elements of the correct type are added to your collections.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top