jdk提供了两个比较器接口,Comparable & Comparator。
Comparable是java.lang包下的一个接口;
Comparator 是JavaSE位于java.util包下的一个接口,该接口高度抽象,不仅要学会使用,更应该思考背后思想!
比较方法 | 场景 | 使用方式 | |
---|---|---|---|
Comparable | compareTo | 简单比较 | 被比较的类自己实现 comparable 接口,重写 compareTo 方法 |
Comparator | compare | 复杂比较 | 在使用的时候实现comparator的匿名内部类,重写compare方法 |
Comparable
Comparable是一个排序接口,一个类实现了Comparable接口,就意味着它本身支持排序,list或者数组实现了这个接口能够自动的进行排序,可以用Collections.sort() 或者 Arrays.sort() 进行排序。
此接口有且只有一个方法:publicint compareTo(T o);
SortedMap 接口的key内置了compareTo方法来进行键排序,SortedSet 也是内置了compareTo方法作为其内部元素的比较手段。
默认升序,compareTo(T o) 方法的返回值来比较大小:
- 当前对象this > 比较对象o,返回 正整数;
- 当前对象this < 形参对象o,返回 负整数;
- 当前对象this = 形参对象o,返回 零。
示例:按照Person对象的age属性降序排序。 ```java public class Main{ public static void main(String[] args){
List<Person> persons = Arrays.asList(
new Person("a", 1),
new Person("q", 3),
new Person("c", 2));
Collections.sort(persons);
System.out.println(persons);
} }
@Data
class Person implements Comparable
public Person(String name , Integer age){
this.name = name;
this.age = age;
}
@Override
public int compareTo(Person p) {
if (this.age < p.age){
return 1;
} else if (this.age > p.age) {
return -1;
}
return 0;
}
}
<a name="STfWp"></a>
## Comparator
什么场景需要做比较,那么什么场景就是Comparator接口的用武之地,常见的场景如 排序、分组等;<br />**How**<br />创建Comparator对象,重写compare方法来指定排序逻辑。<br />可通过如下方式来触发:
1. Stream的成员方法:Stream<T> sorted(Comparator<? super T> comparator);
1. List接口的方法:void sort(Comparator<? super E> c);�
**内置的快速构建工具**<br />Comparator接口还提供了一些静态方法或者默认方法用于快速创建具有特定功能的Comparator实现类。
- Comparator.**comparing**(Function keyExtractor)<br />直接通过返回排序因子进行排序,底层是用的Comparable接口;
- Comparator.**nullsFirst**(Comparator comparator):空元素排在最后面
- #**reversed()**:倒序
- #**thenComparing(...)**:用于指定次排序方案,非常多重载;
<a name="H5AjB"></a>
### 排序
**适用场景**:
- 没有实现 Comparable 接口;
- 实现的 Comparable#comareTo(T o) 方法不符合自己的预期。
**示例:**按照age升序排列Person集合
```java
public class Main{
public static void main(String[] args){
List<Person> list = Arrays.asList(
new Person("a", 1),
new Person("q", 3),
new Person("c", 2));
list.sort(new Comparator<Person>() {
@Override
public int compare(Person p1, Person p2) {
// 升序
return p1.getAge() - p2.getAge();
// 降序
// return p2.getAge() - p1.getAge();
}
});
list.forEach(System.out::println);
}
}
@Data
class Person implements Comparable<Person> {
private String name;
private Integer age;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
}