Java实现对象的比较

本文最后更新于:4 年前

引言

Java中的基本数据类型,如intlong等基本数据类型,可以使用比较运算符 > < = 进行比较大小,但是对于对象数据类型,则不能简单地这样进行比较,需要对象的类实现Comparable接口重写排序规则或通过Comparator进行定制排序,这两种方式都允许开发者自定义排序逻辑,而不是仅依赖于对象的自然顺序。

Comparable接口

含有方法compareTo(obj)

  • 如果当前对象this大于形参obj,则返回正数
  • 如果当前对象this小于形参obj,则返回负数
  • 如果当前对象this等于形参obj,则返回零

自定义类实现Comparable接口

自定义Person

1
2
3
4
5
6
7
8
9
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Person {
private Long id;
private String name;
private int age;
}

Person类如果需要比较大小,需要实现Comparable接口,重写compareTo方法,给定具体的排序规则,如Person对象按年龄从小到大进行排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Data
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
public class Person implements Comparable {

private Long id;
private String name;
private int age;

@Override
public int compareTo(Object o) {
if (!(o instanceof Person)) {
throw new RuntimeException("不能进行比较");
}
Person p = (Person) o;
if (this.age > p.age) {
return 1;
} else if (this.age == p.age) {
return 0; // 还可以再次定义排序规则
} else {
return -1;
}
}
}

Comparator定制排序

可以将Comparator这个接口作为参数传递给排序方法(如Collections.sortArrays.sort),重写方法compare(Object obj1, Object obj2),比较obj1obj2

  • obj1大于obj2,则返回正数
  • obj1小于obj2,则返回负数
  • obj1等于obj2,则返回零

适用于对象没有实现java.lang.Comparable接口、或实现了Comparable接口但想重新定义排序规则的情况,如对person列表进行排序,规则为年龄相同,按id从小到大排序,年龄不同,按年龄从小到大进行排序

1
2
3
4
5
6
7
8
9
10
list.sort(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
if (o1.getAge() != o2.getAge()) {
// 年龄相同
return Integer.compare(o1.getAge(), o2.getAge());
}
return Long.compare(o1.getId(), o2.getId());
}
});

Java8中Lambda表达式对Comparator实现可以进行简化,减少匿名类的冗余代码,如

1
2
3
4
5
6
7
list.sort((o1, o2) -> {
if (o1.getAge() != o2.getAge()) {
// 年龄相同
return Integer.compare(o1.getAge(), o2.getAge());
}
return Long.compare(o1.getId(), o2.getId());
});

对比

Comparable

  • 通过类实现接口、重写比较方法,这样在每次使用的时候就不用重写排序方法,方便、但灵活性较差
  • 当需要定义对象的自然排序时,例如数据库实体通常需要一种自然的排序方式

Comparator

  • 在排序时重写排序方法,每次进行排序比较时需要重写比较方法,麻烦、但灵活性较高
  • 当需要多种排序方式或者排序方式需要频繁更改时,例如根据不同场景进行数据展示时的排序

总结

通过实现Comparator接口,开发者可以控制集合的排序行为,从而使代码更加灵活和强大。无论是对数据库查询结果进行排序,还是对复杂数据结构进行管理,Comparator都是一个非常有用的工具。在使用时,考虑到性能和可读性,选择正确的比较逻辑和排序策略至关重要。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!