COMP2247 - Algorithms and Data Structures

Syllabus Software Installation Assignments Tests
Lectures and Labs
**Back to Full Menu**

Generics Exercises
ArrayListProcessing.java
NameSearching.java
Hardware Store Program With ArrayList




Generics


In this section, we study Java Generics.

Introduction to Generics

A generic class or method is one whose definition uses a placeholder for one or more of the types it works with.

The placeholder is really a type parameter.

For a generic class, the actual type argument is specified when an object of the generic class is being instantiated.

For a generic method, the compiler deduces the actual type argument from the type of data being passed to the method.

Using the Diamond Operator for Type Inference

The ArrayList class is generic: the definition of the class uses a type parameter for the type of the elements that will be stored.

ArrayList<String> specifies a version of the generic ArrayList class that can hold String elements only.

ArrayList<Integer> specifies a version of the generic ArrayList class that can hold Integer elements only.

Instantiation and Use of a Generic Class:

ArrayList<String> myList = new ArrayList<String>();

myList.add(“Java is fun”);

String str = myList.get(0);

Writing Generic Class

Generic Point Class:

Consider a “point” as a pair of coordinates x and y, where x and y can be any type.

The type of x must always be the same as the type of y.

public class Point<T> {

     private T xCoordinate; // The X coordinate
     private T yCoordinate; // The Y coordinate

     public Point(T x, T y) {
          xCoordinate = x;
          yCoordinate = y;
     }

     ...
}


// Create various Point objects in the client program

Point<Integer> iPoint = new Point<>(1, 2);
Point<Double> dPoint = new Point<>(1.5, 2.5);

Only Reference Types Can Be Passed to Type Parameters

Only reference types can be used to declare or instantiate a generic class.

ArrayList<Integer> myIntList = new ArrayList<Integer>; // OK

ArrayList<int>myIntList = new ArrayList<int>; // Error

int is not a reference type, so it cannot be used to declare or instantiate a generic class.

The corresponding wrapper class must be used to instantiate a generic class with a primitive type argument.

Autoboxing and Unboxing

Autoboxing is the automatic conversion of a primitive type to the corresponding wrapper type when it is used in a context where a reference type is required.

Integer intObj = 35; // Autoboxing converts int to Integer

Point<Number> nPoint = new Point<Number>(3.14, 2.71); // double to Number

Unboxing is the automatic unwrapping of a wrapper type to give the corresponding primitive type when the wrapper type is used in a context that requires a primitive type.

int i = new Integer(34); // Unboxing converts Integer to int

Point<Double> p = new Point<Double>(3.14, 2.71); // doubles 3.14, 2.71 to Double

double x = p.getX(); // p.getX() returns Double which is unboxed to double

Instantiating a Generic Class without Specifying a Type Argument

It is possible, but not recommended.

Raw Types

You can create an instance of a generic class without specifying the actual type argument.

An object created in this manner is said to be of a raw type.

Point rawPoint = new Point("Anna", new Integer(26));

System.out.println(rawPoint);

//Output: (Anna, 26)

Raw Types and Casting

The Object type is used for unspecified types in raw types.

When using raw types, it is necessary for the programmer to keep track of types used and use casting:

Point rawPoint = new Point("Anna", new Integer(26));

System.out.println(rawPoint);

String name = (String)rawPoint.getX(); // Cast is needed

int age = (Integer)rawPoint.getY(); // Cast is needed

System.out.println(name);

System.out.println(age);

Commonly Used Type Parameters

Name Meaning
T A generic type
S A generic type
E A genetic type of an element in a collection
K A generic type of a key for a collection that maintains key/value pairs
V A generic type of a value for a collection that maintains key/value pairs