为什么我们在comparator之前使用new关键字,而在排序中使用它作为构造函数,因为comparator是一个接口,所以我们不能实例化它?
Collections.sort(persons, new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
});
这是因为此代码不实例化Comparator
。正如你所说,这是不可能的。
相反,它是语法糖。它是的缩写
// Yes, you can define a class inside a method.
class $AutoGeneratedName implements Comparator<Person> {
@Override public int compare(Person p1, Person p2) {
return p1.getAge() - p2.getAge();
}
}
Collections.sort(persons, new $AutoGeneratedName());
换句话说,就是:定义一个新类,即implements
比较器。然后,立即实例化这个类一次。将整个表达式解析为此新创建的实例的引用。此构造称为匿名内部类。
小心-此代码错误。
20年前,除了一个细节外,这个代码基本上是好的:在比较中使用a - b
对于非常大的数字是危险的,但据推测,考虑到这是关于"年龄"的,这不会是一个问题。尽管如此,糟糕的形式;CCD_ 4会更好。
但从那时起,这就不再需要了。你可以把这个概念写得更短,比如:
Collections.sort(persons, (a, b) -> Integer.compare(a.getAge(), b.getAge());
通过使用List#sort
和Comparator.comparingInt
,我们甚至可以做得更简单、更易读。
persons.sort(Comparator.comparingInt(Person::getAge));
当你像它的英文一样阅读它时,它正是你认为的那样:它通过比较特定的int对集合"persons"进行排序——哪个int?在person方法上调用getAge()
时得到的。
最后一个片段是您应该使用的。