所以我正在学习Comparator和Comparable,我遇到了以下问题。 我有一节课:
extension=protobuf.so
另一个类,Name实现Comparable,并且在构造函数中首先有两个字符串。我不完全理解的是Comparator的功能,我已经阅读了Java文档,我知道它用于对元素进行不同的排序而不更改我的示例中的Name类,它在某些情况下也可以允许空值,但是这个声明在我的类构造函数中工作正常,我根本不需要在PhoneBook类中实现Comparator接口:
public class PhoneBook implements Comparator<Name>{
private SortedMap<Name, Integer> directory ;
//class code constructor etc.
//this is the method that the compiler wants if implementing Comparator
@Override
public int compare(Name o1, Name o2) {
return o1.firstName.compareTo(o2.firstName);
}
}
实现了我希望它实现的功能,而无需通过PhoneBook类实现Comparator接口。我的问题是类何时可能要实现Comparator接口?是否有不同的方法让地图使用不同的排序方法(比类名中的Comparable接口提供的排序方法),而不是在初始化时传递匿名类?如果这个问题不够清楚,或者不适合这个网站,我很抱歉。
编辑:我理解Comparable vs Comparator的论点以及何时使用它们。我的问题更多是关于如何使用Comparator。初始化时,你可以在不通过新的比较器的情况下对地图进行排序吗?类是什么时候实现这个接口的好主意?
答案 0 :(得分:1)
实现Comparator
的类不应该执行任何其他操作。
由于大多数此类仅在一个地方使用,因此将它们实现为未命名非常常见,即与第二个示例中的匿名类一样。
但是,如果您希望Comparator
可以重复使用,那么为它创建一个独立的类是个好主意,例如:在你的例子中命名为FirstNameComparator
。
请注意,在Java 8+中,使用lambda表达式而不是匿名类(因为这在逻辑上是lambda表达式变成了什么)以及可重用比较的方法引用会更容易。
// Using anonymous class (Java 1.2+)
this.directory = new TreeMap<Name, Integer>(new Comparator<Name>() {
@Override
public int compare(Name n1, Name n2) {
return n1.getFirstName().compareTo(n2.getFirstName());
}
});
// Reusable named class (Java 1.2+)
public final class FirstNameComparator implements Comparator<Name> {
@Override
public int compare(Name n1, Name n2) {
return n1.getFirstName().compareTo(n2.getFirstName());
}
}
// Then use it like this:
this.directory = new TreeMap<Name, Integer>(new FirstNameComparator());
// Using lambda expression (Java 8+)
this.directory = new TreeMap<Name, Integer>(
(n1, n2) -> n1.getFirstName().compareTo(n2.getFirstName())
);
// Using method reference (Java 8+)
public class PhoneBook {
public PhoneBook(ArrayList<Name> names, ArrayList<Integer> phones) {
this.directory = new TreeMap<Name, Integer>(PhoneBook::compareFirstName);
// other constructor code
}
private static int compareFirstName(Name n1, Name n2) { // public, if reusable
return n1.getFirstName().compareTo(n2.getFirstName());
}
// other PhoneBook code
}
// Using Comparator helper (Java 8+)
this.directory = new TreeMap<Name, Integer>(Comparator.comparing(Name::getFirstName));