Browse DevX
Sign up for e-mail newsletters from DevX


Creating Custom Generic Collections with J2SE 5.0

J2SE 5.0 introduced many additions to the collections API that you need to be aware of to properly implement generic custom collections that work seamlessly with multiple types and the new "for each" construct.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

y last article discussed how to use J2SE 5.0's new collection features, allowing you to designate a specific type to be used with a collection. Additionally, the new "for each" construct lets you access collections without the need for an "iterator". However, that was only half the story. This article shows you how to create collections that are compatible with the latest features of J2SE.

Creating Classes that Support Generics
First you must lean how to create a class that allows a "generic type". This means that whenever your class is instantiated, you can also specify one or more Java types to be associated with that class. To illustrate this, consider this simple example class presented in Listing 1.

Notice how the class in Listing 1 is declared. It specifies three generics between the beginning angle brackets. Those generics are placeholders for real types. When you declare a class of this type, you can specify a class to take the place of ONE, TWO, and THREE. If you do not, then the class will use the default type of Object.

Here's how to instantiate a class of type Example.

Example example = new Example();

The preceding code substitutes the specific Double, Integer, and String types for the "ONE," "TWO," and "THREE" placeholders in Listing 1. You can see that these variables have these types by the following three lines that set their values.

example.setOne(1.5); example.setTwo(2); example.setThree("Three");

Now that you understand how to create a custom class that makes use of generics, it's far simpler to create a custom collection class that makes use of generics.

Creating a Queue Class
A queue can be a very useful data structure. To understand the functions of a queue picture the line of people waiting for a ride at an amusement park. People enter the line at the back. They wait their turn, and eventually reach the front of the line. The order does not change.

This same principle can be applied to a queue class. There are two methods, named "push" and "pop". You use the push method to place objects onto the queue, and the pop method to remove items from the queue. For example, if you use the push method to add three objects onto the queue, then calling pop three times will remove those three objects in the same order. This is the same as the amusement park line. If three people enter the line in a specific order, they will get access to the ride, in the same order.

The following code shows how to implement a Java queue that makes use of generics.

package com.heatonresearch.examples.collections; import java.util.*; public class Queue<T> { private ArrayList<T> list = new ArrayList<T>(); public void push(T obj) { list.add(obj); } public T pop() throws QueueException { if (size() == 0) throw new QueueException( "Tried to pop something from the queue, " + "when it was empty"); T result = list.get(0); list.remove(0); return result; } public boolean isEmpty() { return list.isEmpty(); } public int size() { return list.size(); } public void clear() { list.clear(); } }

The preceding code declares the queue class so that it accepts one generic type.

public class Queue<T>

The generic type "T" is the class type that will be placed onto the queue. To store the items on a queue, the class creates an ArrayList that accepts types of "T" as well.

The push method is very simple. It accepts a single object, of the generic type "T", and adds it to the ArrayList.

The pop method is slightly more complex. First, if you try to pop an object from the queue, and there are no objects on the queue, the class throws an exception of type QueueException. Here's the QueueException class.

package com.heatonresearch.examples.collections; public class QueueException extends Exception { public QueueException(String msg) { super(msg); } }

Here's the code that throws the QueueException:

if (size() == 0) throw new QueueException( "Tried to pop something from the queue, " + "when it was empty");

If the queue is not empty, the method retrieves the last element from the queue, stores it in a variable named result, then removes that item from the list. The following lines of code accomplish this.

T result = list.get(0); list.remove(0); return result;

Note that the temporary variable is also of the generic type "T". To ensure the greatest level of compatibility when this class is used with real Java types that will "stand in" for the generic type, it's important to always use the generic type whenever you must access these variables.

Thanks for your registration, follow us on our social networks to keep up-to-date