我什么时候应该使用Comparator vs Comparable?



我有一个pojo列表,我需要以某种方式排序。我在POJO类中定义了一个Comprator,并使用它对列表进行排序。

以下方法是正确的/最佳实践吗?有更好的方法吗?

public class CompratorTest {
public static void main(String[] args) {
List<Person> people = List.of(
new Person("zoe", "saturday", 40),
new Person("luca", "red", 15),
new Person("boris", "vin", 54),
new Person("boris", "apple", 33),
new Person("boris", "apple", 70)
);
List<Person> sortedPeople =
people.stream()
.sorted((person, other) -> Person.COMPARATOR.compare(person, other))
.collect(Collectors.toList());
sortedPeople.forEach(System.out::println);
}
@Data
@AllArgsConstructor
static
class Person {
final static Comparator<Person> COMPARATOR =
Comparator.comparing((Person person) -> person.getName())
.thenComparing(person -> person.getSurname())
.thenComparing(person -> person.getAge());
String name;
String surname;
int age;
}
}

输出是正确的,顺便说一下

编辑添加更经典的方式:

@Data
@AllArgsConstructor
static class Animal implements Comparable<Animal> {
String name;
String race;
@Override
public int compareTo(Animal other) {
if (this.name.equals(other.name)) {
return String.CASE_INSENSITIVE_ORDER.compare(this.race, other.race);
}
return String.CASE_INSENSITIVE_ORDER.compare(this.name, other.name);
}
}

你认为哪一个是更好的解决方案?

ComparatorComparable的用例有很大的区别。

实现Comparable接口适用于具有自然顺序的对象在您的域模型中。我不确定动物是否有自然顺序,但如果从应用程序如何对动物建模的角度来看是这样的话,那就好了——这就是要走的路。否则,你的类不应该实现Comparable

这不是基于意见的,文档明确定义何时使用这些接口。

可比:

这个接口对每个类的对象强制一个总的排序这就实现了它。这种排序被称为类的排序自然排序,类的compareTo方法称为这是自然的比较方法。

比较器:

比较器还可用于控制某些数据结构(如已排序集合或已排序映射)的顺序,或用于提供排序对于没有自然排序的对象的集合.

另一个明显的区别是,您可以根据需要定义任意多种类型的比较器。当没有特定的方法来比较和排序对象时,这很方便。它们的名字必须比comparator更有意义。

就我个人而言,我不认为将一对比较器定义为public static final字段有什么大的危害,就像在您的示例中一样。如果你有一个单独的类来管理这种类型的实例——将比较器提取到该类中,否则如果这些对象无处不在并且在许多地方使用,你可以将它们留在POJO中(是基于意见的部分)。

这不是基于意见的:TL;DR实现Comparable:

  • 从语义上讲,这就是接口设计的目的:它们表达了一个由对象强制执行的契约,对象的行为:如果对象是可序列化的,那么它们应该实现Serializable,如果它们是可比较的,那么它们应该实现Comparable,等等……

  • 继承将如预期的那样工作,并且更具可读性:如果你定义了一个扩展AnimalDog,你可以使用超级实现(即狗像任何其他Animal一样进行比较)来实现Dog的比较,或者重写实现来实现特定于Dog的行为。Dog类的用户只需调用instance.compareTo(...),而不必担心她/他应该调用哪个最终静态比较器

  • 使用AnimalAPI的用户知道他们必须在将自己的动物添加到继承树中时实现Comparable

相关内容

  • 没有找到相关文章

最新更新