Index
1. Introduction to Generics
Generics in Java allow you to write flexible, reusable code while ensuring type safety. With generics, you can define classes, interfaces, and methods where the type of data is specified at runtime, but with compile-time checks. This avoids issues like ClassCastException
and removes the need for extensive casting.
For example, consider a simple generic class that holds any type of data:
Here:
T
is a type parameter that stands for any data type (likeInteger
,String
, orCustomClass
).- When you create an instance, you specify the type you want
T
to represent.
This ensures type safety: you can only put a String
in a Box<String>
and an Integer
in a Box<Integer>
.
2. Java Collections
Here’s a link to my Github repository for more in-depth code examples: https://github.com/shasankp000/JavaCollections
The Collections Framework provides a set of classes and interfaces for working with collections of objects, such as lists, sets, and maps. Key interfaces include:
- List: An ordered collection that allows duplicates (e.g.,
ArrayList
,LinkedList
). - Set: An unordered collection that doesn’t allow duplicates (e.g.,
HashSet
,TreeSet
). - Map: A collection of key-value pairs (e.g.,
HashMap
,TreeMap
).
Each collection type supports different operations, and generics enhance their flexibility and safety.
Key Classes in Collections Framework
-
ArrayList
- Resizable array implementation of the
List
interface. - Allows duplicate elements and maintains insertion order.
- Resizable array implementation of the
- HashSet
- Implements the
Set
interface, does not allow duplicate elements, and doesn’t maintain any particular order.
- HashMap
- Implements the
Map
interface, storing key-value pairs. - Keys must be unique; values can be duplicated.
3. Using Generics with Collections
Generics help ensure that your collections only contain objects of a specified type. Here’s how you can use generics with the collections framework:
Without generics, you would have to cast objects when retrieving them from a collection, leading to potential runtime errors. Generics help catch such errors at compile time.
4. Bounded Type Parameters
Sometimes, you may want to restrict the types that can be used with generics to a certain hierarchy. This is where bounded type parameters come in.
Here, T
is constrained to subclasses of Number
, meaning NumberBox
can be instantiated with Integer
, Double
, Float
, etc., but not String
or other types.
5. Wildcards
Wildcards in generics (?
) let you create flexible methods that work with collections of different types. There are three main types of wildcards:
- Unbounded Wildcard (
?
): Allows any type.
- Upper Bounded Wildcard (
? extends Type
): Restricts toType
or any subclass.
- Lower Bounded Wildcard (
? super Type
): Restricts toType
or any superclass.
Putting It All Together
Here’s a complete example using a few different collection types with generics:
This example:
- Uses
ArrayList
andHashSet
with generics to ensure type safety. - Uses a wildcard in
printList
to accept a list of any type. - Uses an upper-bounded wildcard in
sumNumbers
to work with any subclass ofNumber
.