在排序中将比较器用作参数时,我们如何实例化它



为什么我们在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#sortComparator.comparingInt,我们甚至可以做得更简单、更易读。

persons.sort(Comparator.comparingInt(Person::getAge));

当你像它的英文一样阅读它时,它正是你认为的那样:它通过比较特定的int对集合"persons"进行排序——哪个int?在person方法上调用getAge()时得到的。

最后一个片段是您应该使用的。

相关内容