Why is this code throwing a ClassCastException and how to avoid it
-
19-09-2019 - |
Question
Consider this code:
import java.util.*;
class jm45 implements Comparator<jm45>
{
private int x;
jm45(int input) { x = input; }
public static void main( String args[] )
{
List list = new ArrayList();
list.add(new jm45(2));
list.add(new jm45(2));
Collections.sort(list); //faulty line
}
public int compare( jm45 t1 , jm45 t2 )
{
return t1.x - t2.x;
}
}
Solution
Your class implements Comparator<jm45>
instead of Comparable<jm45>
.
A Comparator
knows how to compare two objects - a Comparable
knows how to compare another with itself.
You either need to pass in a comparator for sort()
to use (as the second argument) or the values have to be comparable.
Here's a version which uses the Comparable
interface instead:
import java.util.*;
class Test implements Comparable<Test>
{
private int x;
Test(int input)
{
x = input;
}
public static void main(String args[])
{
List<Test> list = new ArrayList<Test>();
list.add(new Test(2));
list.add(new Test(2));
Collections.sort(list);
}
public int compareTo(Test other)
{
return x - other.x;
}
}
And here's a version which uses the Comparator
interface:
import java.util.*;
class TestComparator implements Comparator<Test>
{
public int compare(Test t1, Test t2)
{
return t1.getX() - t2.getX();
}
}
class Test
{
private int x;
Test(int input)
{
x = input;
}
int getX()
{
return x;
}
public static void main(String args[])
{
List<Test> list = new ArrayList<Test>();
list.add(new Test(2));
list.add(new Test(2));
Collections.sort(list, new TestComparator());
}
}
There's nothing to stop a class implementing Comparator<T>
for itself, but it's a little strange for it to do so. For instance, you wouldn't normally ask one string to compare two other ones with each other - it's got nothing to do with the original string itself.
OTHER TIPS
From the Collections.sort javaDoc:
Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list).
Your class implements Comparator, not Comparable.