首页 > Java, 挨踢(IT) > 简易Java(14):ComparableComparator

简易Java(14):ComparableComparator

2014年11月9日 发表评论 阅读评论 273 人阅读    

ComparableComparator是Java核心API提供的两个接口(interface)。从它们的名字就可以看出,他们用于比较对象的大小。但是,确切来说,它们到底是什么呢?以及它们直接有什么不同之处呢?接下来的两个例子来回答这个问题。这个简单的例子就是比较两种HDTV的尺寸。当阅读完下面的代码,你就知道如何使用ComparableComparator

1、Comparable

一个类实现Comparable接口,是为了可以让其自身的对象和其他对象进行比较。类本身必须实现这个接口,为的是可以和它自己的实例进行比较。要求实现的方法是compareTo()。下面的这个例子来展示它的用法:

package com.diguage.books.simplejava.ar14.comparable;

/**
 * Comparable接口使用示例
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-03 17:53
 */
public class HDTV implements Comparable<HDTV> {
    private int size;
    private String brand;

    public HDTV(int size, String brand) {
        this.size = size;
        this.brand = brand;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    @Override
    public int compareTo(HDTV tv) {
        if (this.getSize() > tv.getSize()) {
            return 1;
        } else if (this.getSize() < tv.getSize()) {
            return -1;
        } else {
            return 0;
        }
    }
}



package com.diguage.books.simplejava.ar14.comparable;

/**
 * 运行入口
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-03 17:55
 */
public class Main {
    public static void main(String[] args) {
        HDTV tv1 = new HDTV(55, "Samsung");
        HDTV tv2 = new HDTV(60, "Sony");
        if (tv1.compareTo(tv2) > 0) {
            System.out.println(tv1.getBrand() + " is better.");
        } else {
            System.out.println(tv2.getBrand() + " is better.");
        }
    }
}

运行该程序,输入如下:

Sony is better.

2、Comparator

对于比较对象间的不同属性,Comparator能更好的胜任。例如,两个人可以基于nameage进行比较等。(这些情况,Comparable就不可以胜任了。)

必须实现compare()方法。现在,让我们使用其他方式来比较这些TV的尺寸。Comparator的常用方法是排序。CollectionsArrays类都提供了一个可以使用Comparator的排序方法。例子如下:

package com.diguage.books.simplejava.ar14.comparator;

/**
 * Model类
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-03 18:36
 */
public class HDTV {
    private int size;
    private String brand;

    public HDTV(int size, String brand) {
        this.size = size;
        this.brand = brand;
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }
}


package com.diguage.books.simplejava.ar14.comparator;

import java.util.Comparator;

/**
 * Comparator使用示例
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-03 19:10
 */
public class SizeComparator implements Comparator<HDTV> {
    @Override
    public int compare(HDTV tv1, HDTV tv2) {
        int tv1Size = tv1.getSize();
        int tv2Size = tv2.getSize();
        if (tv1Size > tv2Size) {
            return 1;
        } else if (tv1Size < tv2Size) {
            return -1;
        } else {
            return 0;
        }
    }
}


package com.diguage.books.simplejava.ar14.comparator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Comparator示例主类
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-03 18:34
 */
public class Main {
    public static void main(String[] args) {
        HDTV tv1 = new HDTV(55, "Samsung");
        HDTV tv2 = new HDTV(60, "Sony");
        HDTV tv3 = new HDTV(42, "Panasonic");
        List<HDTV> tvs = new ArrayList<HDTV>();
        tvs.add(tv1);
        tvs.add(tv2);
        tvs.add(tv3);
        Collections.sort(tvs, new SizeComparator());
        for (HDTV hdtv : tvs) {
            System.out.println(hdtv.getBrand());
        }
    }
}

运行改程序,输入如下:

Panasonic
Samsung
Sony

我们经常会使用Collections.reverseOrder()来获取一个倒序的Comparator。例如:

package com.diguage.books.simplejava.ar14;

import java.util.*;

/**
 * Collections.reverseOrder()和Comparator的搭配使用。
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-08 23:19
 */
public class CollectionsTestMain {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(3);
        list.add(1);
        list.add(2);
        System.out.println(list);

        Collections.sort(list);
        System.out.println(list);

        Comparator<Integer> comparator = Collections.reverseOrder();
        Collections.sort(list, comparator);
        System.out.println(list);
    }
}

运行该程序,输入如下:

[3, 1, 2]
[1, 2, 3]
[3, 2, 1]

3、如何选择呢?

简单来说,一个实现Comparable接口的类具有可比性,意思就是说它的实例相互直接可以进行比较。

一个实现Comparator接口的类就一个比较器(Comparator),相对于其他类。首先,它可以被传入排序方法,例如Collections.sort()Arrays.sort(),可精确控制排序顺序;其次,它还可以被用于控制已有的某行数据结构的顺序,例如排序的set或排序的map。

例如,创建TreeSet,我们可以在构造函数中传入一个Comparator,或者将一个类添加可比性。

方式一:TreeSetComparator比较器)

package com.diguage.books.simplejava.ar14.treesetcomparator;

/**
 * Dog
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-03 19:40
 */
public class Dog {
    int size;

    public Dog(int size) {
        this.size = size;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "size=" + size +
                '}';
    }
}


package com.diguage.books.simplejava.ar14.treesetcomparator;

import java.util.Comparator;

/**
 * Dog的比较器
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-09 08:33
 */
public class SizeComparator implements Comparator<Dog> {
    @Override
    public int compare(Dog d1, Dog d2) {
        return d1.size - d2.size;
    }
}


package com.diguage.books.simplejava.ar14.treesetcomparator;

import java.util.TreeSet;

/**
 * Comparator示例主类
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-09 08:35
 */
public class ImpComparableMain {
    public static void main(String[] args) {
        TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // 传入比较器
        d.add(new Dog(2));
        d.add(new Dog(1));
        d.add(new Dog(3));
        System.out.println(d);
    }
}

方式二:实现Comparable

package com.diguage.books.simplejava.ar14.treesetcomparable;

/**
 * Dog类
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-09 08:41
 */
public class Dog implements Comparable<Dog> {
    int size;

    public Dog(int size) {
        this.size = size;
    }

    @Override
    public int compareTo(Dog o) {
        return o.size - this.size;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "size=" + size +
                '}';
    }
}


package com.diguage.books.simplejava.ar14.treesetcomparable;

import java.util.TreeSet;

/**
 * Comparable示例主类
 * <p/>
 * Coder:D瓜哥,http://www.diguage.com/
 * <p/>
 * Date: 2014-11-09 08:43
 */
public class ImpComparableMain {
    public static void main(String[] args) {
        TreeSet<Dog> d = new TreeSet<Dog>();
        d.add(new Dog(1));
        d.add(new Dog(2));
        d.add(new Dog(3));

        System.out.println(d);
    }
}

《Simple Java》是一本讲解Java面试题的书。讲解也有不少独特之处,为了面试,《简易Java》走起!



作 者: D瓜哥,https://www.diguage.com/
原文链接:https://wordpress.diguage.com/archives/120.html
版权声明:非特殊声明均为本站原创作品,转载时请注明作者和原文链接。

分类: Java, 挨踢(IT) 标签: ,
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.