Java Language – 31 – Generics

Collections and Data Structures – Generics
Introduction

Generics are an essential feature in Java that allow you to create classes and methods capable of working with different data types while ensuring type safety. In this guide, we’ll explore the concept of generics, understand their significance, and learn how to use them in Java to create flexible and type-safe collections and data structures.

What Are Generics?

Generics provide the ability to create classes, interfaces, and methods that operate on parameters of various data types. They allow you to define classes or methods with type parameters (placeholders for actual data types) and enforce type safety at compile time.

Defining Generic Classes

You can define generic classes in Java by using angle brackets and type parameters. Here’s an example of a simple generic class that stores and retrieves a single value of any data type:


public class Box<T> {
    private T value;

    public Box() {
        // Constructor
    }

    public void setValue(T value) {
        this.value = value;
    }

    public T getValue() {
        return value;
    }

In this example, the ‘Box’ class is generic, with the type parameter ‘T.’ It can store and retrieve a value of any data type provided during its usage.

Using Generic Classes

You can use generic classes by providing the actual data type when creating an instance. Here’s how you can use the ‘Box’ class to store and retrieve an integer value:


public class GenericExample {
    public static void main(String[] args) {
        Box<Integer> intBox = new Box<>();  // Create a Box for Integer
        intBox.setValue(42);

        // Retrieve the value (no casting needed)
        int value = intBox.getValue();
        System.out.println("Value: " + value);
    }

In this example, we create a ‘Box’ specifically for ‘Integer’ values. This ensures type safety, and you can retrieve the value without casting.

Benefits of Generics

Generics offer several advantages:

  • Type Safety: Generics prevent runtime type errors by enforcing type checking at compile time.
  • Code Reusability: You can create generic classes and methods that work with various data types, promoting code reusability.
  • Improved Readability: Generics make your code more readable and self-explanatory by specifying the data type explicitly.
Generic Interfaces and Methods

Besides generic classes, you can also define generic interfaces and methods. For example, the ‘List’ interface in the Java Collections Framework is generic and can work with different types of elements.


public interface List<E> {
    void add(E element);
    E get(int index);

In this example, ‘List’ is a generic interface that can work with elements of any data type. You can implement this interface to create lists of specific data types.

Using Generic Methods

Generic methods allow you to create methods that are parameterized with data types. Here’s an example of a generic method that swaps two elements in an array:


public class GenericMethods {
    public static <T> void swap(T[] array, int i, int j) {
        T temp = array[i];
        array[i] = array[j];
        array[j] = temp;
    }

    public static void main(String[] args) {
        Integer[] intArray = {1, 2, 3};
        swap(intArray, 0, 2);

        for (Integer value : intArray) {
            System.out.println(value);
        }
    }

In this example, the ‘swap’ method is a generic method that can swap elements of any data type. It ensures type safety while providing flexibility.

Conclusion

Generics are a powerful feature in Java that allow you to create flexible and type-safe classes, interfaces, and methods. By using generics, you can enhance code reusability, readability, and type safety in your Java applications.