天天看點

Android學習之使用Comparable或Comparator比較和排序元素

Comparable和Comparator都是用來實作集合中元素的比較、排序的。

Comparable是在集合内部定義的方法實作的排序,而Comparator是在集合外部實作的排序,如果想實作排序,就需要在集合外定義Comparator接口的方法或在集合内實作Comparable接口的方法。

這裡用一個年齡和姓名相同時自動覆寫之前的記錄的例子來講下Comparable和Comparator的使用:

先看下Comparable:

/**
 * Student
 *
 * @author yuzhentao
 */
public class Student implements Comparable<Student> {

    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Student)) {
            throw new ClassCastException("不是學生對象");
        }
        Student s = (Student) o;
        return this.name.equals(s.name) && this.age == s.age;
    }

    @Override
    public int compareTo(@NonNull Student another) {
        /**
         * compareTo():大于0表示前一個資料比後一個資料大, 0表示相等,小于0表示前一個資料小于後一個資料
         * 相等時會走到equals(),這裡講姓名年齡都一樣的對象當作一個對象
         */
        int num = Integer.valueOf(this.age).compareTo(another.age);//先比較年齡
        if (num == 0) {
            return this.name.compareTo(another.name);//如果年齡相同,再比較姓名(姓名按Unicode編碼升序排序)
        }
        return num;
    }

}      

先寫個學生類實作Comparable接口,重寫compareTo()方法,這裡按照年齡升序排列,并實作hashCode()和equals(),這兩個方法要用來比較當年齡和姓名都相同時的處理。都相同時覆寫之前的一條記錄。還要實作toString(),最後列印的Student對象就是以toString()的格式列印出來。

compareTo()傳回值大于0表示前一個資料比後一個資料大, 0表示相等,小于0表示前一個資料小于後二個資料,相等時會走到equals(),這裡将姓名年齡都一樣的對象當作一個對象。

然後是主界面:

/**
 * 主界面
 *
 * @author yuzhentao
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
    }

    private void initData() {
        TreeMap<Student, String> map = new TreeMap<>();
        map.put(new Student("a", 28), "北京");
        map.put(new Student("b", 23), "上海");
        map.put(new Student("c", 22), "南京");
        map.put(new Student("c", 22), "深圳");//此Key與上面的相同,會将上面的Value覆寫
        map.put(new Student("d", 25), "杭州");
        map.put(new Student("d", 25), "廣州");//此Key與上面的相同,會将上面的Value覆寫
        Set<Map.Entry<Student, String>> set = map.entrySet();
        Iterator<Map.Entry<Student, String>> iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry<Student, String> entry = iterator.next();
            Student student = entry.getKey();
            String address = entry.getValue();
            Log.e("yuzhentao", "Student=" + student + " Address=" + address);
        }
    }

}      

這裡使用一個TreeMap來存儲鍵值對,然後使用Iterator來取出集合裡面的鍵值,使用TreeMap可以排序,至于規則就是比較器裡定義的規則了。

然後看下結果:

03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='c', age=22} Address=深圳

03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='b', age=23} Address=上海

03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='d', age=25} Address=廣州

03-30 13:54:53.155 10419-10419/? E/yuzhentao: Student=Student{name='a', age=28} Address=北京

再看下Comparator:

Comparator使用和Comparable差不多,就是形式上有點不一樣,也是先寫個學生類,不過不用繼承,但是其他方法要寫好

/**
 * Student
 *
 * @author yuzhentao
 */
public class Student {

    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

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

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public boolean equals(Object o) {
        if (!(o instanceof Student)) {
            throw new ClassCastException("不是學生對象");
        }
        Student s = (Student) o;
        return this.name.equals(s.name) && this.age == s.age;
    }

}      

然後是實作Comparator,這裡要使用get方法來得到值

/**
 * StudentComparator
 *
 * @author yuzhentao
 */
public class StudentComparator implements Comparator<Student> {

    @Override
    public int compare(Student lhs, Student rhs) {
        /**
         * compareTo():大于0表示前一個資料比後一個資料大, 0表示相等,小于0表示前一個資料小于後一個資料
         * 相等時會走到equals(),這裡講姓名年齡都一樣的對象當作一個對象
         */
        int num = Integer.valueOf(lhs.getAge()).compareTo(rhs.getAge());//先比較年齡
        if (num == 0) {
            return lhs.getName().compareTo(rhs.getName());//如果年齡相同,再比較姓名(姓名按Unicode編碼升序排序)
        }
        return num;
    }

}      

最後是主界面,這裡還是使用TreeMap,因為可以傳入Comparator

/**
 * 主界面
 *
 * @author yuzhentao
 */
public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
    }

    private void initData() {
        TreeMap<Student, String> map = new TreeMap<>(new StudentComparator());
        map.put(new Student("a", 28), "北京");
        map.put(new Student("b", 23), "上海");
        map.put(new Student("c", 22), "南京");
        map.put(new Student("c", 22), "深圳");//此Key與上面的相同,會将上面的Value覆寫
        map.put(new Student("d", 25), "杭州");
        map.put(new Student("d", 25), "廣州");//此Key與上面的相同,會将上面的Value覆寫
        Set<Map.Entry<Student, String>> set = map.entrySet();
        Iterator<Map.Entry<Student, String>> iterator = set.iterator();
        while (iterator.hasNext()) {
            Map.Entry<Student, String> entry = iterator.next();
            Student student = entry.getKey();
            String address = entry.getValue();
            Log.e("yuzhentao", "Student=" + student + " Address=" + address);
        }
    }

}      

看下結果:

03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='c', age=22} Address=深圳

03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='b', age=23} Address=上海

03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='d', age=25} Address=廣州

03-30 14:01:17.374 22341-22341/? E/yuzhentao: Student=Student{name='a', age=28} Address=北京

希望對各位有所幫助。

Demo位址:http://download.csdn.net/detail/qq_23940659/9476637

Demo位址:http://download.csdn.net/detail/qq_23940659/9476698