Unique Queues

Scenario:
We want to create a queue with elements of certain type which are to be determined at run time. Furthermore we do not want to add the object to the queue if it is already in the queue.

Solution[1]:
We could use generics, introduced in Java 1.5, to create a queue that contains only one type of elements. However, generics are implemented in Java by converting the code to Reflection code.

 

To create the queue we consider two constructors. The first constructor only takes one parameter, the type of the elements to be stored in the queue. We store the type and create a new Array using the type with a size of zero. The second constructor takes in the type as well as a Method. The method equalsMethod is used to test if two elements are equal in the contains method. The constructor also tests to see if equalsMethod is valid method by making sure it is a static method, the return type is boolean, there are two parameters both of type eltType.

 

Below is a code fragment from the constructor:

 

Class[] param = equalsMethod.getParameterTypes();

//check for valid equals method
if(Modifier.isStatic(equalsMethod.getModifiers())
    && equalsMethod.getReturnType() == boolean.class
    && param[0]==eltType
    && param[1]==eltType
    && param.length==2){

    this.equalsMethod=equalsMethod;
    this.eltType=eltType;
    eltArray = Array.newInstance(eltType, 0);
}

 

The add method first tests if the object to be added is of the same type as specified at runtime. It then checks if the element to be added is already contained in queue by calling the contains method.

 

The contains method first checks if an equalsMethod has been specified. If it has not, then contains method of dataList (an Array) is used to check. If however, a equalsMethod method has been specified via the constructor, a call is made to the equalsMethod of the object to be added with two arguments: the object to be added and the element from dataList we are comparing the object to be added to.

 

Below is a code fragment from contains method:

 

if(equalsMethod == null)
    return dataList.contains(e);
else{
    for (int i=0;i<dataList.size();i++){
        Object[] args = {e,dataList.get(i)};
        if((Boolean) equalsMethod.invoke(e,args))
            return true;
    }
    return false;
}

 

Conclusion:
The use of Reflection easily materializes the solution. We use Reflection first in the constructors to create an Array of certain data type by using the newInstance call.  We also use Reflection to see if equalsMethod provided in the constructor is valid by looking at its modifiers, parameter types, and return type.

 

In the add method, we use the isInstance method to check if the element we have to add is of the same type as the queue’s elements.

 

In the contains method, we use Reflection to invoke equalsMethod with certain arguments.

 

Without Reflection we could not create with ease a queue that adds only elements of certain type and checks to see if that element is already in the queue.


 

[1] Solution adapted from Java Reflection in Action.

Source Code (UniqueQueue.java)


Home
Previous Example
Next Example
Source Code
References
Questions?