Dan*_*Dan 163 java sorting comparator
我学会了如何使用比较器,但我对比较器有困难.我的代码中有错误:
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)
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
我相信它必须在比较方法中对铸造做一些事情,但我正在玩它仍然无法找到解决方案
Bar*_*ers 207
你的示例类有几个尴尬的事情:
price
和info
(更多的东西对象,而不是人);无论如何,这是一个如何使用的演示Comparator<T>
:
public class ComparatorDemo {
public static void main(String[] args) {
List<Person> 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<Person> {
@Override
public int compare(Person a, Person b) {
return a.name.compareToIgnoreCase(b.name);
}
}
class AgeComparator implements Comparator<Person> {
@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);
}
}
Run Code Online (Sandbox Code Playgroud)
等效的Java 8演示如下所示:
public class ComparatorDemo {
public static void main(String[] args) {
List<Person> 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);
}
}
Run Code Online (Sandbox Code Playgroud)
and*_*per 150
这是一个超短的模板,可以立即进行排序:
Collections.sort(people,new Comparator<Person>(){
@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 (meaning the order stays the same)
}
});
Run Code Online (Sandbox Code Playgroud)
如果难以记住,请尽量记住它与类似的符号(就数字的符号而言):
lhs-rhs
Run Code Online (Sandbox Code Playgroud)
如果你想按升序排序:从最小的数字到最大的数字.
pol*_*nts 36
使用People implements Comparable<People>
代替; 这定义了自然顺序People
.
A Comparator<People>
也可以另外定义,但People implements Comparator<People>
不是正确的做事方式.
两个重载Collections.sort
是不同的:
<T extends Comparable<? super T>> void sort(List<T> list)
Comparable
利用其自然排序的对象<T> void sort(List<T> list, Comparator<? super T> c)
Comparator
你通过尝试排序来混淆两者Comparator
(这也是为什么它没有意义Person implements Comparator<Person>
).再次,要使用Collections.sort
,您需要其中一个是真的:
Comparable
(使用1-arg sort
)Comparator
必须提供类型的A (使用2-args sort
)另外,不要在新代码中使用原始类型.原始类型是不安全的,并且仅提供兼容性.
也就是说,而不是这个:
ArrayList peps = new ArrayList(); // BAD!!! No generic safety!
Run Code Online (Sandbox Code Playgroud)
你应该使用这样的类型安全泛型声明:
List<People> peps = new ArrayList<People>(); // GOOD!!!
Run Code Online (Sandbox Code Playgroud)
然后你会发现你的代码甚至没有编译!! 这将是一件好事,因为代码有问题(Person
没有implements Comparable<Person>
),但是因为你使用了原始类型,编译器没有检查这个,而是你ClassCastException
在运行时得到了!!!
这应该说服您始终在新代码中使用类型安全泛型类型.总是.
Num*_*our 14
为了完整起见,这是一个简单的单线compare
方法:
Collections.sort(people, new Comparator<Person>() {
@Override
public int compare(Person lhs, Person rhs) {
return Integer.signum(lhs.getId() - rhs.getId());
}
});
Run Code Online (Sandbox Code Playgroud)
Java 8增加了一种制作Comparators的新方法,可以减少你必须编写的代码量,Comparator.comparing.另请查看Comparator.reversed
这是一个样本
import org.junit.Test;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import static org.junit.Assert.assertTrue;
public class ComparatorTest {
@Test
public void test() {
List<Person> peopleList = new ArrayList<>();
peopleList.add(new Person("A", 1000));
peopleList.add(new Person("B", 1));
peopleList.add(new Person("C", 50));
peopleList.add(new Person("Z", 500));
//sort by name, ascending
peopleList.sort(Comparator.comparing(Person::getName));
assertTrue(peopleList.get(0).getName().equals("A"));
assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("Z"));
//sort by name, descending
peopleList.sort(Comparator.comparing(Person::getName).reversed());
assertTrue(peopleList.get(0).getName().equals("Z"));
assertTrue(peopleList.get(peopleList.size() - 1).getName().equals("A"));
//sort by age, ascending
peopleList.sort(Comparator.comparing(Person::getAge));
assertTrue(peopleList.get(0).getAge() == 1);
assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1000);
//sort by age, descending
peopleList.sort(Comparator.comparing(Person::getAge).reversed());
assertTrue(peopleList.get(0).getAge() == 1000);
assertTrue(peopleList.get(peopleList.size() - 1).getAge() == 1);
}
class Person {
String name;
int age;
Person(String n, int a) {
name = n;
age = a;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
}
}
Run Code Online (Sandbox Code Playgroud)
为了完整性。
使用 Java8
people.sort(Comparator.comparingInt(People::getId));
Run Code Online (Sandbox Code Playgroud)
如果你想在 descending order
people.sort(Comparator.comparingInt(People::getId).reversed());
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
490877 次 |
最近记录: |