Generics in Java

In some recent posts, I’ve created generic data structures in Java (see Linked List and Hashtable). When I say generic, I mean you could store any type of data in the data structure. That’s true since it uses an Object as its data type, and all classes extend Object. However, you might fall foul of some typing errors.

For example, let’s say create a LinkedList and add a String to it. Then you forget it’s supposed to be a list of Strings, and you add an object of type Car to it. Car and String are not the same and there may be issues down the line when you assume that your LinkedList contains only a single type, for example if you try iterate the list and call the getNumberOfDoors() method on a String object (that you thought was a Car object) – you’d get an exception of some sort.

Java has supported Generics for some time now, and I thought it was time to add support for Generics into my data structures. This means that it’s more type safe. When you create an object of type LinkedList, you tell it that you want it to hold Strings, and if you try add a Car, it will give you a compile-time error; so fewer run-time issues related to type assumptions.

In general, here are a few pointers about adding support for Generics to your own classes. The examples in my Github repository already have this.

– Tell your class that it’s generic. In the class declaration, use angle-brackets and letters of your choice to denote any type. You can indicate that you expect the type to have a certain super-type or implement a certain interface. In this case, I’d like all data added to be of the same type and to implement Comparable (and Comparable with generics is Comparable of course).

public class LinkedList<T extends Comparable<T>>
public class Hashtable<K extends Comparable<K>, V extends Comparable<V>>

– Your data variable(s) should be generic types. Use the same letter as you chose when declaring the class.

private ListNode<T> firstNode;

– Change your methods to accept/return generic types.

public void add(T inputData)

– Change any internal references to constructors to use generics.

ListNode<T> node = new ListNode<T>(inputData);

– Instantiate your class like any other generic data type.

LinkedList<String> list = new LinkedList<String>();
Hashtable<String, String> table = new Hashtable<String, String>();