2

I'm trying to create a genetic ArrayList of my class Team but I can't cast Comparable to T despite that T extends Comparable

(I tried extends Comparable without putting < T > and same problem is happening)

public class ArrayList<T extends Comparable>
{
    static int MaxSize = 1003;//some random maximum size for our array lists
    public int Size = 0;
    public int Capacity = 0;
    T[] MyList;
    public ArrayList()//Default Constructor
    {
        this(MaxSize);
    }
    public ArrayList(int Capacity)
    {

        MyList = (T[]) new Comparable[Capacity]; // Casting
    }
}
public class Team implements Comparable<Team>
{
    public String Name;
    public int Points;
    public int GamesCount;
    public int Wins;
    public int Loses;
    public int GoalDifference;//Goals Scored - Goals Against
    public int GoalsScored;
    public int GoalsAgainst;
    public Team(String s)
    {
      Name = s;
      Points = 0;
      GamesCount = 0;
      Wins = Loses = 0;
      GoalDifference = GoalsAgainst = GoalsScored = 0;
    }
}
public class Test
{
 public static void main(String args[])
  {
     ArrayList<Team> Teams = new ArrayList<Team>(10);
            for(int i = 0 ;i < 10;i++)
            {
                String TeamName = in.next();
                Teams.MyList[i] = new Team(TeamName);//exception here
            }
  }
}

I am getting the following exception. Many thanks in advance for your help.

Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Comparable; cannot be cast to [LTeam; at Test.main(Test.java:21)

Soumen Mukherjee
  • 2,953
  • 3
  • 22
  • 34
  • Casting an `Animal` to a `Cat` will not work. The animal might also be a `Dog` or anything. Only the other way around makes sense, casting a `Cat` to an `Animal`. Since all cats are also animals. – Zabuzard Feb 16 '19 at 12:23
  • What version of Java are you using? Maybe I'm missing something but I can't reproduce the problem using Java 11.0.2. _Unrelated_: Please learn Java naming conventions and use them; doing so makes it easier for other Java developers to read your code. – Slaw Feb 16 '19 at 12:33
  • Java Version 8 update 181 – Mohamad Ziad Alkabakibi Feb 16 '19 at 12:57

3 Answers3

2

That's obvious, just think about it for a second.

new Comparable[Capacity];

Here you're creating an array which will contain Comparable elements.
Then you're trying to downcast it to an array of Team, which means trying to use a more specific type, and which is not allowed (Upcasting and downcasting in Java), and as you see, throws a ClassCastException.

As your array will contain only types which extends Comparable, you can have a Comparable array inside your ArrayList implementation.

Comparable[] MyList;

Then you can initialize it without casting

MyList = new Comparable[Capacity];

And remember to implement the Comparable#compareTo method in your Team class, otherwise the code won't compile.


You asked for an example.

public class ArrayList<T extends Comparable> {
    private static final int MAX_SIZE = 1000;
    private final Comparable<T>[] list;

    public ArrayList() {
        this(MAX_SIZE);
    }

    public ArrayList(int capacity) {
        list = new Comparable[capacity]; // Casting
    }

    public T get(final int index) {
        return (T) list[index];
    }

    public void set(final int index, final T value) {
        list[index] = value;
    }
}

Usage is pretty simple

final ArrayList<Team> teamArrayList = new ArrayList<>(3);
teamArrayList.set(0, new Team("One"));
teamArrayList.set(1, new Team("Two"));
teamArrayList.set(2, new Team("Three"));

final String name = teamArrayList.get(0).Name;

As you extended the Comparable<T> interface, you need to implement it

Compares this object with the specified object for order. Returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object

A basic example is

@Override
public int compareTo(final Team other) {
    return name.compareTo(other.name);
}
LppEdd
  • 20,274
  • 11
  • 84
  • 139
0

In your code, T is Team.

Team IS-A Comparable. Hence, you can cast Team to Comparable.

But every Comparable is not a Team. Therefore, Comparable cannot be cast to Team.

Prasad Karunagoda
  • 2,048
  • 2
  • 12
  • 16
0

watch this statement: MyList = (T[]) new Comparable[Capacity]; it initializes an array from Comparable interface and put it in to MyList field with type of Team[]. you can test it with:

{
    MyList = (T[]) new Comparable[Capacity]; // Casting
    System.out.println( MyList.getClass().toString());
}

it writes class [Ljava.lang.Comparable; in output... so in the first attempt to access this field from outside of class you will get ClassCastException even by calling length in test method like this:

public class Test
{
    public static void main(String args[])
    {
        MArrayList<Team> Teams = new MArrayList<Team>(10);
        int length = Teams.MyList.length; // this line throws ClassCastException 
        ....
    }
}

To solve your problem I suggest change your ArrayList class like this:

public class ArrayList<T extends Comparable<T>>
{
    ...
    Comparable<T>[] MyList;
    ...
    public ArrayList(int Capacity)
    {
        MyList = new Comparable[Capacity]; // Casting
    }
}
e gh
  • 1