通过Comparator接口理解策略模式

169 阅读1分钟

在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));
    }
}