Generics with Collections
Last Updated :
04 Aug, 2025
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?
- Type Safety: Ensures only the specified type can be added to the collection, preventing accidental insertion of the wrong type.
- Avoid Casting: Eliminates the need for explicit type casting when retrieving elements from the collection.
- Code Reusability: The same generic class or method can be reused with different data types without rewriting code.
- 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);
}
}
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);
}
}
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>
}
}
OutputGeeks
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
Java Enterprise Edition
Multithreading
Concurrency
JDBC (Java Database Connectivity)
Java Frameworks
JUnit