I learned how to use the comparable but I'm having difficulty with the Comparator. I am having a error in my code:
Exception in thread "main" java.lang.ClassCastException: New.People cannot be cast to java.lang.Comparable
at java.util.Arrays.mergeSort(Unknown Source)
at java.util.Arrays.sort(Unknown Source)
at java.util.Collections.sort(Unknown Source)
at New.TestPeople.main(TestPeople.java:18)
Here is my code:
import java.util.Comparator;
public class People implements Comparator {
private int id;
private String info;
private double price;
public People(int newid, String newinfo, double newprice) {
setid(newid);
setinfo(newinfo);
setprice(newprice);
}
public int getid() {
return id;
}
public void setid(int id) {
this.id = id;
}
public String getinfo() {
return info;
}
public void setinfo(String info) {
this.info = info;
}
public double getprice() {
return price;
}
public void setprice(double price) {
this.price = price;
}
public int compare(Object obj1, Object obj2) {
Integer p1 = ((People) obj1).getid();
Integer p2 = ((People) obj2).getid();
if (p1 > p2) {
return 1;
} else if (p1 < p2){
return -1;
} else {
return 0;
}
}
}
import java.util.ArrayList;
import java.util.Collections;
public class TestPeople {
public static void main(String[] args) {
ArrayList peps = new ArrayList();
peps.add(new People(123, "M", 14.25));
peps.add(new People(234, "M", 6.21));
peps.add(new People(362, "F", 9.23));
peps.add(new People(111, "M", 65.99));
peps.add(new People(535, "F", 9.23));
Collections.sort(peps);
for (int i = 0; i < peps.size(); i++){
System.out.println(peps.get(i));
}
}
}
I believe it has to do something with the casting in the compare method but I was playing around with it and still could not find the solution
Here's a super short template to do the sorting right away :
if it's hard to remember, try to just remember that it's similar (in terms of the sign of the number) to:
That's in case you want to sort in ascending order : from smallest number to largest number.
Here's an example of a Comparator that will work for any zero arg method that returns a Comparable. Does something like this exist in a jdk or library?
You want to implement Comparable, not Comparator. You need to implement the compareTo method. You're close though. Comparator is a "3rd party" comparison routine. Comparable is that this object can be compared with another.
Note, you may want to check for nulls in here for getId..just in case.
For the sake of completeness, here's a simple one-liner
compare
method:Use
People implements Comparable<People>
instead; this defines the natural ordering forPeople
.A
Comparator<People>
can also be defined in addition, butPeople implements Comparator<People>
is not the right way of doing things.The two overloads for
Collections.sort
are different:<T extends Comparable<? super T>> void sort(List<T> list)
Comparable
objects using their natural ordering<T> void sort(List<T> list, Comparator<? super T> c)
Comparator
You're confusing the two by trying to sort a
Comparator
(which is again why it doesn't make sense thatPerson implements Comparator<Person>
). Again, to useCollections.sort
, you need one of these to be true:Comparable
(use the 1-argsort
)Comparator
for the type must be provided (use the 2-argssort
)Related questions
Also, do not use raw types in new code. Raw types are unsafe, and it's provided only for compatibility.
That is, instead of this:
you should've used the typesafe generic declaration like this:
You will then find that your code doesn't even compile!! That would be a good thing, because there IS something wrong with the code (
Person
does notimplements Comparable<Person>
), but because you used raw type, the compiler didn't check for this, and instead you get aClassCastException
at run-time!!!This should convince you to always use typesafe generic types in new code. Always.
See also
You should use the overloaded sort(peps, new People()) method