Open In App

Generics with Collections

Last Updated : 04 Aug, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

In Java, Generics with Collections allow you to define the type of elements a collection can hold. This adds type safety, so you can avoid errors like inserting the wrong type of data and needing to cast objects manually. For example, using List<String> ensures that only strings can be added to the list

Why Use Generics with Collections?

  1. Type Safety: Ensures only the specified type can be added to the collection, preventing accidental insertion of the wrong type.
  2. Avoid Casting: Eliminates the need for explicit type casting when retrieving elements from the collection.
  3. Code Reusability: The same generic class or method can be reused with different data types without rewriting code.
  4. Improved Readability and Maintainability: Clearly specifies the type of elements stored, making the code easier to understand and maintain.

Syntax of Generics with Collection

CollectionType<Type> collectionName = new CollectionType<>();

Example with ArrayList:

Java
import java.util.ArrayList;

public class Geeks {
    public static void main(String[] args)
    {
        // Creating a generic ArrayList that stores only Strings
        ArrayList<String> msg = new ArrayList<>();

        msg.add("Hello");
        msg.add("Geeks");

        // No need for type casting
        String str1 = msg.get(0);
        String str2 = msg.get(1);

        System.out.println(str1+" "+ str2); 
    }
}

Output
Hello Geeks

Explanation:

  • Type-safe list: ArrayList<String> allows only String values.
  • No casting: Directly retrieves elements without explicit type casting.
  • Clean and safe: Improves code readability and avoids runtime errors.

Generic Methods with Collections

Generic methods allow you to define a method with a type parameter, making it reusable for different data types. When combined with collections, they provide flexibility and type safety.

Syntax:

Java
public <T> void methodName(T param) {
    // Method body
}

Implementation: Print Elements of Any Collection

Java
import java.util.*;

public class Geeks{

    // Generic method to print any collection
    public static <T> void printCollection(Collection<T> collection) {
        for (T item : collection) {
            System.out.print(item);
        }
    }

    public static void main(String[] args) {
        List<String> names = Arrays.asList("Geeks", "for", "Geeks");

        printCollection(names);   
    }
}

Output
GeeksforGeeks

Explanation:

  • Generic method <T> allows printCollection to work with any data type.
  • Accepts any Collection<T>, ensuring flexibility (e.g., List, Set).
  • Iterates and prints elements without knowing their exact type.

Wildcard (?) in Generics

In Java Generics, the wildcard ? is used to represent an unknown type. It allows methods to operate on collections of objects without knowing the exact type parameter.

Types of Wildcards

1. Unbounded Wildcard (?): Represents an unknown type. And it can be accept any type of object

List<?> list = new ArrayList<String>();

2. Upper Bounded Wildcard (? extends Type): Accepts Type or its subclasses. It is useful for reading data (but not writing).

List<? extends Number> numbers = new ArrayList<Integer>();

3. Lower Bounded Wildcard (? super Type): Accepts Type or its superclasses. Useful for writing data to the collection.

List<? super Integer> list = new ArrayList<Number>();

Example: Using Unbounded Wildcard

Java
import java.util.*;

public class Geeks{

    // Method accepts any type of List
    public static void printList(List<?> list) {
        for (Object item : list) {
            System.out.println(item);
        }
    }

    public static void main(String[] args) {
        List<String> strList = Arrays.asList("Geeks", "for", "Geeks");
        List<Integer> intList = Arrays.asList(1, 2, 3);

        printList(strList);  // Works with List<String>
        printList(intList);  // Works with List<Integer>
    }
}

Output
Geeks
for
Geeks
1
2
3

Explanation:

  • List<?> allows the method printList to accept any type of list (String, Integer, etc.).
  • The loop iterates through the list and prints each element as an Object.
  • This demonstrates unbounded wildcard usage, making the method flexible and reusable across different types of collections.

Advantages and disadvantages of using Generics with Collections

Advantages

  • Generics prevents insertion of incompatible data types.
  • Generics eliminates the need for explicit casting.
  • Generics can improve code reusability.

disadvantages

  • Generics syntax can be harder to read for beginners.
  • Generics don’t support primitives like int, double directly.
  • Generic type info is removed at runtime, limiting reflection.

Explore