📌  相关文章
📜  使用带有用户定义对象的比较器对 TreeMap 中的键进行排序的Java程序(1)

📅  最后修改于: 2023-12-03 15:36:39.377000             🧑  作者: Mango

使用带有用户定义对象的比较器对 TreeMap 中的键进行排序的Java程序

在Java中,TreeMap是一个有序的Map实现,它通过Comparator或Comparable接口使其键值有序排列。然而,当我们需要使用自定义对象作为TreeMap的键时,可以通过编写自己的比较器来实现排序。

使用Comparable接口

Comparable接口定义了一个compareTo()方法,我们可以在自定义对象中实现该方法,来指定对象之间的比较规则。对于TreeMap而言,当我们将自定义对象作为其键时,它会根据compareTo()方法的返回值来确定键值的排序方式。

以下是一个实现Comparable接口的例子:

public class Person implements Comparable<Person> {
    private String name;
    private int age;

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

    @Override
    public int compareTo(Person o) {
        if (this.age < o.age) {
            return -1;
        } else if (this.age > o.age) {
            return 1;
        } else {
            return 0;
        }
    }
}

在上面的例子中,我们定义了一个Person类,并实现了Comparable接口。在compareTo()方法中,我们根据年龄来进行对象之间的比较。如果当前对象的年龄小于参数对象的年龄,返回-1;如果当前对象的年龄大于参数对象的年龄,返回1;如果两个对象的年龄相等,返回0。

接下来,我们可以使用Person作为TreeMap的键,这样我们就可以根据年龄对键值进行排序了。以下是一个使用Person作为键值的例子:

TreeMap<Person, String> map = new TreeMap<>();
map.put(new Person("Jack", 20), "Jack's value");
map.put(new Person("Tom", 18), "Tom's value");
map.put(new Person("Lucy", 25), "Lucy's value");

for (Map.Entry<Person, String> entry : map.entrySet()) {
    System.out.println(entry.getKey().getName() + " -> " + entry.getValue());
}

上面的例子中,我们分别以23岁、20岁和18岁的年龄创建了三个Person对象,并将它们作为TreeMap的键值。由于我们实现了compareTo()方法来定义对象的比较规则,因此TreeMap会根据该方法的返回值来对键值进行排序。

输出结果为:

Tom -> Tom's value
Jack -> Jack's value
Lucy -> Lucy's value

结果显示,按照年龄进行排序,Tom、Jack、Lucy依次排列。

使用Comparator接口

Comparable接口是自定义对象排序的常见方式,但它有一个缺点:它只能在定义类时指定排序规则,即不能同时使用不同的排序规则。当我们需要根据不同的规则进行排序时,可以使用Comparator接口来实现。

Comparator接口有一个compare()方法,我们可以在自定义一个比较器类,并实现该方法来指定对象之间的比较规则。对于TreeMap而言,我们可以在构造函数中传递比较器对象来指定键值的排序方式。

以下是一个实现Comparator接口的例子:

public class PersonAgeComparator implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        if (o1.getAge() < o2.getAge()) {
            return -1;
        } else if (o1.getAge() > o2.getAge()) {
            return 1;
        } else {
            return 0;
        }
    }
}

在上面的例子中,我们定义了一个PersonAgeComparator类,它实现了Comparator接口,并实现了compare()方法。在compare()方法中,我们与前面实现Comparable接口时的compareTo()方法相同,根据对象的年龄来比较两个对象之间的大小。

接下来,我们可以直接使用PersonAgeComparator对象来创建TreeMap,并在构造函数中传递该对象,指定键值的排序方式。以下是一个使用PersonAgeComparator作为比较器的例子:

TreeMap<Person, String> map = new TreeMap<>(new PersonAgeComparator());
map.put(new Person("Jack", 20), "Jack's value");
map.put(new Person("Tom", 18), "Tom's value");
map.put(new Person("Lucy", 25), "Lucy's value");

for (Map.Entry<Person, String> entry : map.entrySet()) {
    System.out.println(entry.getKey().getName() + " -> " + entry.getValue());
}

上面的例子中,我们创建了一个PersonAgeComparator对象,并使用它来创建一个TreeMap。在put() 方法中,我们向TreeMap中添加了三个Person对象作为键值,由于我们提供了PersonAgeComparator比较器对象,因此TreeMap会根据该对象的compare()方法来对键值进行排序。

输出结果为:

Tom -> Tom's value
Jack -> Jack's value
Lucy -> Lucy's value

结果显示,按照年龄进行排序,Tom、Jack、Lucy依次排列。

小结

当我们需要使用自定义对象作为TreeMap的键时,为了对键值进行排序,我们可以实现Comparable接口或Comparator接口中的compare()方法,并在TreeMap的构造函数中传递比较对象来指定排序规则。这样,我们就能够使用自定义对象进行排序了。