Comparable与Comparator元素比较
一、概述
元素排序主要有两个接口Comparable和Comparator接口。二者还是有所区别的,如下图:
图片转自:本链接
在排序的比较规则中,需要注意1,-1和0三个数值,举例如下:
if(map.get(o1) < map.get(o2)){
return 1;
}else if(map.get(o1) > map.get(o2)){
return -1;
}
return 0;
可以简单理解成,1是将元素排在右边,-1则是排在左边,0则是值相同的情况覆盖。
二、练习demo
2.1 Comparable
People实体类
package element_compare.comparable_ex;
public class People implements Comparable<People>{
private String name;
private int age;
private int id;
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
", id=" + id +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public People(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public People() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int compareTo(People o) {
if(this.getAge() < o.getAge()){
return -1;
}else if(this.getAge() > o.getAge()){
return 1;
}
return 0;
}
}
Test测试类
package element_compare.comparable_ex;
import java.util.ArrayList;
import java.util.Collections;
public class Test {
public static void main(String[] args) {
People p1 = new People("zhangsan",33,3);
People p2 = new People("lisi",20,2);
People p3 = new People("wangwu",30,2);
ArrayList<People> list = new ArrayList<>();
list.add(p1);
list.add(p2);
list.add(p3);
//调用Collections.sort()排序
Collections.sort(list);
System.out.println(list);
}
}
2.2 Comparator
Car实体类
package element_compare.comparator_ex;
import java.util.Comparator;
public class Car{
private int id;
private String name;
private int cost;
public Car() {
}
@Override
public String toString() {
return "Car{" +
"id=" + id +
", name='" + name + '\'' +
", cost=" + cost +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCost() {
return cost;
}
public void setCost(int cost) {
this.cost = cost;
}
public Car(int id, String name, int cost) {
this.id = id;
this.name = name;
this.cost = cost;
}
}
Test测试类
package element_compare.comparator_ex;
import javax.management.ConstructorParameters;
import java.util.*;
public class Test {
public static void main(String[] args) {
Car car1 = new Car(3,"bz",25);
Car car2 = new Car(2,"wl",40);
Car car3 = new Car(6,"hw",26);
HashMap<Car,Integer> map = new HashMap<>();
map.put(car1,6);
map.put(car2,7);
map.put(car3,7);
List<Car> list = new ArrayList<>();
list.add(car1);
list.add(car2);
list.add(car3);
//使用Comparator的匿名内部类
Collections.sort(list, new Comparator<Car>() {
@Override
public int compare(Car o1, Car o2) {
if(map.get(o1) < map.get(o2)){
return 1;
}else if(map.get(o1) > map.get(o2)){
return -1;
}
return 0;
}
});
System.out.println(list);
}
}
2.3 将排序方法抽象成类
将排序方法抽象成类CompareSort01
import java.util.Comparator;
public class CompareSort01 implements Comparator<Car> {
@Override
public int compare(Car o1, Car o2) {
return o1.getId() == o2.getId() ? o2.getCost() - o1.getCost() : o1.getId()-o2.getId();
}
}
测试类
//自定义排序
Car c1 = new Car(3,"A",300);
Car c2 = new Car(3,"B",400);
Car c3 = new Car(2,"C",100);
TreeMap<Car,Integer> t3 = new TreeMap<>(new CompareSort01());
t3.put(c1,1);
t3.put(c2,2);
t3.put(c3,3);
System.out.println(t3);
2.4 小结
1、Comparable和Comparator都是顶级接口,类可以通过继承接口,并重写比较方法实现元素比较,Comparable的是compareTo方法,Comparator的是compare方法,并且Comparator可以通过匿名内部类的方式直接调用,不需要在类内部重新比较方法。
2、compareTo方法的比较需要类内部元素,this做比较,而compare可以使用三方类。因此,Comparable 必须由自定义类内部实现排序方法,而 Comparator 是外部定义并实现排序的。
3、使用TreeMap,为了解耦,可以将排序方法抽象成类,在创建TreeMap对象时,作为参数传入。