算法 - 比较器 - Comparator

比较器

当排序不是程序的主要内容时,使用自定义比较器能够较快的实现排序目的。需要实现 Comparator 接口。

/**
 * 比较器
 */
public class ComparatorTest01 {
    public static void main(String[] args) {
        Integer[] arr = {4, 5, 3, 2, 4, 5, 6, 72, 4, 7, 2, 4};
        Arrays.sort(arr, new MyComparator());
        System.out.println(Arrays.toString(arr));
    }
}

class MyComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        return o2 - o1;
    }
}

在构建 PriorityQueue 、 TreeMap 、 TreeSet 时可以传入一个比较器,这时候加入自定义数据类型就会根据制定的比较器规则进行排序。

举个例子:设计一个比较的类 Person,将会对 Person 类的属性 id 进行比较。

class Person {
    private int id;
    private String name;

    public Person() {
    }

    public Person(int id, String name) {
        this.id = id;
        this.name = name;
    }

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

    @Override
    public String toString() {
        return "Person{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

然后设计一个比较器 IdComparator,将

class IdComparator implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        return o2.getId() - o1.getId();
    }
}

测试一下

public class ComparatorTest02 {
    public static void main(String[] args) {
        Person p1 = new Person(1, "张三");
        Person p2 = new Person(2, "李四");
        Person p3 = new Person(3, "王五");

        TreeSet<Person> set = new TreeSet<>(new IdComparator());
        set.add(p1);
        set.add(p2);
        set.add(p3);

        for (Person p : set) {
            System.out.println(p);
        }
    }
}
output:
Person{id=3, name='王五'}
Person{id=2, name='李四'}
Person{id=1, name='张三'}

查看以上的输出结果,自定义比较器做到了以 Id 降序比较,TreeSet 构建方法传入了比较器。

比较器的一点思考

class MyComparator implements Comparator<Integer> {
    @Override
    public int compare(Integer o1, Integer o2) {
        //return o1 - o2; //语句一
        return o2 - o1; //语句二
    }
}

首先要知道,o1 是需要比较的数,o2 是一个标准,比较过程是

o1 - o2 
	结果为负,则 o1 排到 o2 的前面,此时说明 o1 的数值小于 o2
	结果为正,则 o1 排到 o2 的后面,此时说明 o1 的数值大于 o2
	结果为0,则 o1 和 o2 并排,此时说明 o1 的数值等于 o2
这种排序方式是从小到大升序排列

o2 - o1 
	结果为负,则 o1 排到 o2 的前面,此时说明 o1 的数值大于 o2 
	(此处需要停顿思考一下)
    ···
这种排序方式是从大到小降序排列

因为单纯记住结论并不能很好的理解,所以通过这种记录的方式能够更好的理解比较器的比较方式。

posted @ 2019-11-20 20:14  学习趁早  阅读(496)  评论(0编辑  收藏  举报