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:
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:
public <T> void methodName(T param) {
// Method body
}
Implementation: Print Elements of Any Collection
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
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.