问题
我学会了如何使用可比较的,但我对比较器有困难。我的代码中有错误:
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)
这是我的代码:
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));
}
}
}
我相信它必须在比较方法中对铸造做一些事情,但我正在玩它仍然无法找到解决方案
#1 热门回答(182 赞)
你的示例类有几个尴尬的事情:
它被称为人,虽然它有价格和信息(更多的东西对象,而不是人);
当将一个类命名为复数时,它表明它是一个不止一件事的抽象。
无论如何,这是一个如何使用aComparator的演示:
public class ComparatorDemo {
public static void main(String[] args) {
List people = Arrays.asList(
new Person("Joe", 24),
new Person("Pete", 18),
new Person("Chris", 21)
);
Collections.sort(people, new LexicographicComparator());
System.out.println(people);
Collections.sort(people, new AgeComparator());
System.out.println(people);
}
}
class LexicographicComparator implements Comparator {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
class AgeComparator implements Comparator {
@Override
public int compare(Person a, Person b) {
return a.age < b.age ? -1 : a.age == b.age ? 0 : 1;
}
}
class Person {
String name;
int age;
Person(String n, int a) {
name = n;
age = a;
}
@Override
public String toString() {
return String.format("{name=%s, age=%d}", name, age);
}
}
##编辑
等效的Java 8演示如下所示:
public class ComparatorDemo {
public static void main(String[] args) {
List people = Arrays.asList(
new Person("Joe", 24),
new Person("Pete", 18),
new Person("Chris", 21)
);
Collections.sort(people, (a, b) -> a.name.compareToIgnoreCase(b.name));
System.out.println(people);
Collections.sort(people, (a, b) -> a.age < b.age ? -1 : a.age == b.age ? 0 : 1);
System.out.println(people);
}
}
#2 热门回答(115 赞)
这是一个超短的模板,可以立即进行排序:
Collections.sort(people,new Comparator(){
@Override
public int compare(final Person lhs,Person rhs) {
//TODO return 1 if rhs should be before lhs
// return -1 if lhs should be before rhs
// return 0 otherwise
}
});
如果难以记住,请尽量记住它与类似的符号(就数字的符号而言):
lhs-rhs
如果你想按升序排序:从最小数字到最大数字。
#3 热门回答(32 赞)
UsePeople implements Comparableinstead;这定义了People的自然顺序。
AComparator也可以另外定义,但是People implements Comparator不是正确的做事方式。
Collections.sort的两个重载不同:
> void sort(List list)使用自然顺序对Comparable对象进行排序
void sort(List list,Comparator c)使用兼容的Comparator对任何内容进行排序
你通过尝试排序aComparator来混淆两者(这也是为什么它没有意义的Person implements Comparator)。同样,要使用Collections.sort,你需要其中一个为真:
类型必须是Comparable(使用1-arg排序)
必须提供该类型的比较器(使用2-args排序)
###相关问题
何时使用Comparable vs Comparator
排序联系人的ArrayList
此外,不使用新代码中的原始类型。原始类型是不安全的,并且它仅提供兼容性。
也就是说,而不是这个:
ArrayList peps = new ArrayList(); // BAD!!! No generic safety!
你应该使用这样的类型安全泛型声明:
List peps = new ArrayList(); // GOOD!!!
然后你会发现**你的代码甚至没有编译!!**这将是一件好事,因为代码有问题(Person不是implements Comparable),但是因为你使用了原始类型,编译器没有检查这个,而是你获得aClassCastExceptionat运行时!!!
这应该说服你始终在新代码中使用类型安全泛型类型。总是。
也可以看看
什么是原始类型,为什么我们不应该使用它?