在Java中,如果我们想要比较两个对象,一般会让这个对象实现Comparable接口。比如,在下面的代码中,Person类有两个属性,分别是height和weight。为了比较大小,我们这里重写了compareTo方法,通过height属性进行比较。
public class Person implements Comparable<Person> {
private Integer height;
private Integer weight;
public Person(Integer height, Integer weight) {
this.height = height;
this.weight = weight;
}
public Integer getHeight() {
return height;
}
public Integer getWeight() {
return weight;
}
@Override
public int compareTo(Person o) {
if (this.height > o.height) {
return 1;
} else if (Objects.equals(this.height, o.height)) {
return 0;
} else {
return -1;
}
}
}
但是,如果我们以后想改变比较策略,根据weight属性进行比较的话,就需要重写compareTo方法,将之前的代码删除,这种操作其实是不优雅的,可拓展性也不高。
所以,为了实现更好的可拓展性,我们这里可以使用策略模式,通过实现Comparator接口,自己定义多个比较器。
public class PersonHeightComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
if (o1.getHeight() < o2.getHeight()) {
return -1;
} else if (Objects.equals(o1.getHeight(), o2.getHeight())) {
return 0;
} else {
return 1;
}
}
}
public class PersonWeightComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
if (o1.getWeight() < o2.getWeight()) {
return -1;
} else if (Objects.equals(o1.getWeight(), o2.getWeight())) {
return 0;
} else {
return 1;
}
}
}
之后再根据不同的场景选择不同的比较器。
比如,在Sorter这个类中,我们定义了一个叫做sorted的方法,这个方法可以根据我们传入的比较器对Person数组进行比较:
public class Sorter<T> {
public void sorted(T[] array, Comparator<T> comparator) {
for (int i = 0; i < array.length - 1; i++) {
for (int j = 0; j < array.length - 1 - i; j++) {
if (comparator.compare(array[j], array[j + 1]) > 0) {
swap(array, j);
}
}
}
}
private void swap(T[] array, int j) {
T temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
public static void main(String[] args) {
Sorter<Person> personSorter = new Sorter<>();
Person[] personArray = {new Person(170), new Person(165), new Person(180)};
personSorter.sorted(personArray, new PersonComparator());
System.out.println(Arrays.toString(personArray));
}
}