我什么时候应该使用比较器与可比的?
我有一个需要以某种方式进行分类的pojos列表。我在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);
}
}
您认为哪一种是更好的解决方案?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
比较器
和可比性
之间的用例之间有一个很大的区别。实现
可比
接口适用于在域模型中具有自然顺序的对象。我不确定动物是否具有自然秩序,但是从您的应用程序如何建模动物的角度来看,这是可以的。否则,您的班级不应实现可比性
。这不是基于意见的东西,文档清楚地定义了何时使用这些接口。
另一个明显的区别,您可以根据需要定义比较器的多种口味。当没有一种特定方法比较和分类对象时,这很方便。而且它们必须比
比较器
具有更有意义的名称。就您个人而言,我认为将几个比较器定义为
公共静态最终
字段,这并没有造成巨大伤害。如果您有一个类型的实例的单个类 - 将比较器提取到该类中,否则如果这些对象无处不在并且在许多地方使用,则可以将它们放在POJO内部(基于意见的部分)。There's a substantial distinction between the use cases for
Comparator
andComparable
.Implementing the
Comparable
interface is suitable for objects that have a natural order in your domain model. I'm not sure whether animals have a natural order, but if it is the case from the perspective of how your application model the animals, that's fine - that's the way to go. Otherwise, your class should not implementComparable
.It's not something opinion-based, documentation clearly defines when these interfaces are intended to be used.
Comparable:
Comparator:
Another obvious distinction, that you can define as many flavors of comparators as you need. Which is handy when there's no one specific way to compare and sort the objects. And they must have more meaningful names than
comparator
.Personally, I don't see a huge harm in defining a couple of comparators as
public static final
fields, as in your example. If you have a single class that manages the instances of this type - extract the comparators into that class, otherwise if these objects are ubiquitous and used in many places you can leave them right inside the POJO (that an opinion based part).这不是基于意见的:tl; dr Imparace <代码>可比:
语义上,这是界面设计的目的:它们表达由对象执行的合同,对象的行为:如果对象可以序列化,然后他们应该实现
序列化
,如果它们是可比的,则应实现可比
等...继承将按预期工作,并且更可读性:如果定义了扩展
Animal dog
>您可以使用超级实现(即像任何其他Animal
>)或覆盖实施以实施特定于>
。狗。您的的行为的
dog
dog
类的用户简单地调用instance.compareto(...)
,而不必担心她/他应该致电的最终静态比较器
用户的 最终静态比较器
动物
API知道他们必须在将自己的动物添加到继承树时必须实现
可比性
This is not opinion based: TL;DR implement
Comparable
:semantically, this is what Interfaces are designed for: they express a contract enforced by an object, a behavior of the object: if the objects are serializable, then they should implement
Serializable
, if they are comparable, then they should implementComparable
, etc...inheritance will work as expected and be more readable: if you define a
Dog
that extendsAnimal
, you can implement comparison forDog
using the super implementation (i.e. a Dog is compared like any otherAnimal
) or overriding the implementation to implement a behavior specific toDog
. The user of yourDog
class simply callsinstance.compareTo(...)
without having to worry about what final static comparator she/he should callusers of your
Animal
API know they have to implementComparable
when adding their own animal to the inheritance tree