Java编程:Comparable和Comparator接口

 

Comparable<T>

T - the type of objects that this object may be compared to

Comparator<T>

T - the type of objects that may be compared by this comparator

相同点:都是用于对象比较、排序

 

Interface in java.lang (提供基础类)

Interface in java.util (提供工具类)

 

This interface imposes a total ordering on the objects of each class that implements it.

自然排序:T类自身控制比较方式

一个类实现Comparable接口即表示自身支持排序,Comparable相当于内部比较器:实现Comparable接口的类通过重写接口的compareTo方法,从自身内部控制对象的排序方式

A comparison function, which imposes a total ordering on some collection of objects.

定制排序:T类外创建比较器,比较器控制T类对象比较方式

一个类实现Comparator接口后,就成了比较器类,它的对象就相当于外部比较器,T就是这个比较器要控制排序方式的类类型,在比较器类中以T类的对象为compare方法的参数重写compare方法,从T类外部控制T类对象的排序方式

方法

int compareTo(T o)

T类重写此方法指定排序方式

int compare(T o1, T o2)

比较器类重写此方法指定T对象排序方式

 

适用于自定义类

(很多常见类都实现了Comparable接口:String,Integer,Enum,File...)

适用于自定义类

或无法通过Comparable接口改变排序方式的常见类

或者用于要将比较器用于多类的情况(比如用多态)

 

1、以T类的对象为元素的List可以调用Collections.sort()或Arrays.sort()对List排序

2、T类的对象可用作有序映射(如TreeMap)中的键Key,或有序集合(如TreeSet)中的元素,不需要指定比较器

1、以T类的对象为元素的List可以调用Collections.sort()或Arrays.sort()对List排序,并通过传入比较器指定T对象的排序方式

2、T类的对象可用作有序映射(如TreeMap)中的键Key,或有序集合(如TreeSet)中的元素,并通过传入比较器指定T对象的排序方式

例程

public class Tmp implements Comparable<Tmp>{       

         public int compareTo(Tmp e){

                  // compare this.e and e

}

}

ArrayList<Tmp> elist=new ArrayList<Tmp>();

{elist.add….}

Collections.sort(elist);

TreeSet<Tmp> eset=new TreeSet<Tmp>();

{eset.add…}

 

public class CmpTmp implements Comparator<Tmp>{

         public int compare(Tmp e1, Tmp e2){

                   // compare e1 and e2

         }

}

ArrayList<Tmp> elist=new ArrayList<Tmp> ();

{elist.add….}

CmpTmp cmp=new CmpTmp();

Collections.sort(elist, cmp);

cmp.compare(e1,e2);

TreeSet<Tmp> eset=new TreeSet<Tmp>(cmp);

{eset.add…}

练习:

import java.util.ArrayList;
import java.util.Collections;
import java.util.TreeSet;

public class CompareTest {
    public static void main(String args[]) {
        ArrayList<Person> plist = new ArrayList<>();
        plist.add(new Person("A", 30));
        plist.add(new Person("B", 20));
        plist.add(new Person("C", 10));
        System.out.println("Original:" + plist);

        Collections.sort(plist);  // Person按姓名排序实现的Comparable
        System.out.println("NameOrder:" + plist);

        //PersonComparator是按年龄排序的比较器类
        PersonComparator cmp = new PersonComparator();
        System.out.println(plist.get(0).getName() + " age compare with " + plist.get(1).getName() + " age = " + cmp.compare(plist.get(0), plist.get(1)));

        Collections.sort(plist, cmp); //指定按照年龄排序
        System.out.println("AgeOrder:" + plist);

        //两种方式建立Person的有序集合
        TreeSet<Person> pset1=new TreeSet<Person>();
        pset1.add(new Person("Ada",22));
        pset1.add(new Person("Bob",11));
        System.out.println("Comparable: "+pset1);

        TreeSet<Person> pset2=new TreeSet<Person>(cmp);
        pset2.add(new Person("ada",22));
        pset2.add(new Person("Bob",11));
        System.out.println("Comparator:"+pset2);

    }
}
// 被比较的类:Person
import java.lang.Comparable;

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

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int compareTo(Person other) {  //Person按姓名排序重写Comparable的compareTo()
        return name.compareTo(other.getName());
    }

    @Override
    public String toString(){  //如果不重写自定义类的toString,输出的就是hashCode
        return name+"("+age+")";
    }
}
// 比较器类:PersonComparator 
import java.util.Comparator;

public class PersonComparator implements Comparator<Person> {
    @Override
    public int compare(Person p1, Person p2) {  //比较器按年龄排序
        return p1.getAge() - p2.getAge();
    }
}

输出:

猜你喜欢

转载自blog.csdn.net/EVEcho/article/details/86490004