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
- Introduction
checkedMap()Method Syntax- Examples
- Basic Usage with Checked Map
- Using Checked Map with Custom Classes
- Real-World Use Case
- 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:
NullPointerExceptionif 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.