views:

347

answers:

4

I'm having problems trying to pass an Integer object from a driver class as an argument for function of a SortedArray Generic class I created. From my driver class, I convert the user's int input into an Integer object to be cast onto Comparable of my SortedArray class.

I continue to receive the error: "Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to Comparable". I took a look at some of my classmates' source codes only to find little difference in setting the arguments/parameters yet they have their code working just fine. I've been looking for hours trying to find what error I've made and I still can't find why my Integer object can't be cast to Comparable.

Here's a bit from my SortedArray Class

public class SortedArray implements Comparable{
    public int size;
public int increment;
public int top;
    Comparable[] a = new Comparable [size];

public SortedArray(int initialSize, int incrementAmount)
{
        top = -1;
        size = initialSize;
        increment = incrementAmount;

}
public int appropriatePosition(Comparable value)
{
        int hold = 0;
        if(top == -1)
        {
            return 0;
        }
        else
        {    
            for(int i = 0; i <= top; i++)
            {
                if(a[i].compareTo(value) > 0)
                {
                    hold = i;
                    break;
                }
            }
        }
        return hold;
}

public void insert(Comparable value) //The function that my driver class needs to access
{
        //Shifting numbers to the top
        if(full() == true)
        {
            Comparable[] tempArray = new Comparable[top + increment];
            for(int i= 0; i< size; i++)
            {
                tempArray[i]= a[i];
                a  = tempArray;
            }
            size = top + increment;
        }
        if(a[appropriatePosition(value) + 1] != null)
        {
            for(int i = top; i < appropriatePosition(value); i--)
            {
                a[i + 1] = a[i];
            }
        }
        a[appropriatePosition(value) + 1]= value;
    }

Here's the code for my driver class that passes Integer Object insertObj as an argument for SortedArray's insert function.

public class IntDriver  {
 public static void main(String[] args)
 {
     Scanner keyboard = new Scanner(System.in);
     //Creating variables
     int data;
     boolean check = false;
     int choice;
     int size = 5;
     int increment = 3;
     SortedArray b = new SortedArray(size, increment);
     //Creating Menu
     while(check == false)
     {
     System.out.println("Please choose through options 1-6.");
     System.out.println("1. Insert\n2. Delete\n3. Clear\n4. Smallest\n5. Largest\n6. Exit");
     choice = keyboard.nextInt();
     switch(choice)
         {
         case 1:
             System.out.println("Type the int data to store in array location.");
             data = keyboard.nextInt();
             Integer insertObj = new Integer(data);
             b.insert(insertObj);// Here's where I lay "insertObj" as an argument for the SortedArray function.
             System.out.println("The value " + data + " is inserted");
            break;
A: 

Integer implements Comparable<Integer> which means that it has a method with signature:

int compareTo(Integer i)

Objects which implement (and therefore can be casted to) Comparable must have a method with signature:

int compareTo(Object o)

Since Integer does not have a Compare method that can take any object, it cannot be cast as a Comparable. Comparable is a 1.4.2 interface, while Comparable<T> is a 1.5 interface.

EDIT: If you are using the 1.4.2 version of Integer, then what I am telling you is incorrect. However, 1.5 Integers cannot be cast as Comparable.

Brett Widmeier
its `int compareTo(Integer i)` and not `int CompareTo(Integer i)`. Similarly its `int compare(Object o)` and not `int Compare(object o)`.Java is case sensitive.
Harsha
Yeah, they both should be `compareTo`. All set now.
Brett Widmeier
Hmm, this compiles and runs fine in 1.5: `Comparable c = new Integer(1);` `Integer` extends generic type `Comparable<Integer>`, but it can be casted to the raw type `Comparable`
axtavt
Also its `Object` and not `object`.
Harsha
This is not true... otherwise TreeSet could not be written anymore. The Javadoc for <http://java.sun.com/javase/6/docs/api/java/util/TreeSet.html#TreeSet()> says that all elements need to implement Comparable, and Integer can be used as a key for a TreeSet...
Paul Wagland
-1 since the information given here is wrong.
Paul Wagland
Any class that implements Comparable<Something> will have compareTo(Object) synthetic bridge method that will "redirect" to compareTo(Something). So you definitely CAN cast to raw Comparable, but it's better to get your types sorted out and avoid the cast.
Yardena
-1 no matter what Java version, `java.lang.Integer`'s can always be casted to a `java.lang.Comparabe`: they implement the interface after all!
Bart Kiers
A: 

I haven't put too much effort into this, but wouldn't it just be easier to use a SortedSet implementation (or its child interface NavigableSet) like TreeSet rather than write your own class? That is, unless you wanted duplicate elements...

R. Bemrose
"I took a look at some of my classmates' source codes" I'm thinking that this class is his assignment.
Brett Widmeier
Good point. I've retagged the question with the homework tag.
R. Bemrose
+3  A: 

The problem is that Integer extends java.lang.Comparable, then your Comparable is not a java.lang.Comparable. Look at the error message, your Comparable comes from the default package rather than java.lang:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to Comparable

That is, you can't cast java.lang.Integer to your own class

axtavt
+3  A: 

As mentioned by axtavt, the problem is that you have your own class Comparable. More specifically, what that means is that:

Integer.valueOf(1) instanceof java.util.Comparable == true
Integer.valueOf(1) instanceof Comparable == false

This means that somewhere in your code you have something like:

Object[] a = new Object[] {Integer.valueOf(1);};
Comparable x = (Comparable) a[0];
// or something equivalent, this is likely being passed through layers
// and not being done next to each other like this.

You need to change that to:

Object[] a = new Object[] {Integer.valueOf(1);};
java.util.Comparable x = (java.util.Comparable) a[0];

Even better, you should rename your Comparator class to something that doesn't collide with the standard classes in Java. In general, even though Java has namespacing, you should try to avoid your classes having the same name as the system classes to avoid exactly this kind of confusion.

Paul Wagland