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

简易Java(14):ComparableComparator

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

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

1、Comparable

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

01package com.diguage.books.simplejava.ar14.comparable;
02 
03/**
04 * Comparable接口使用示例
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-03 17:53
09 */
10public class HDTV implements Comparable<HDTV> {
11    private int size;
12    private String brand;
13 
14    public HDTV(int size, String brand) {
15        this.size = size;
16        this.brand = brand;
17    }
18 
19    public int getSize() {
20        return size;
21    }
22 
23    public void setSize(int size) {
24        this.size = size;
25    }
26 
27    public String getBrand() {
28        return brand;
29    }
30 
31    public void setBrand(String brand) {
32        this.brand = brand;
33    }
34 
35    @Override
36    public int compareTo(HDTV tv) {
37        if (this.getSize() > tv.getSize()) {
38            return 1;
39        } else if (this.getSize() < tv.getSize()) {
40            return -1;
41        } else {
42            return 0;
43        }
44    }
45}
46 
47 
48 
49package com.diguage.books.simplejava.ar14.comparable;
50 
51/**
52 * 运行入口
53 * <p/>
54 * Coder:D瓜哥,http://www.diguage.com/
55 * <p/>
56 * Date: 2014-11-03 17:55
57 */
58public class Main {
59    public static void main(String[] args) {
60        HDTV tv1 = new HDTV(55, "Samsung");
61        HDTV tv2 = new HDTV(60, "Sony");
62        if (tv1.compareTo(tv2) > 0) {
63            System.out.println(tv1.getBrand() + " is better.");
64        } else {
65            System.out.println(tv2.getBrand() + " is better.");
66        }
67    }
68}

运行该程序,输入如下:

2、Comparator

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

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

01package com.diguage.books.simplejava.ar14.comparator;
02 
03/**
04 * Model类
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-03 18:36
09 */
10public class HDTV {
11    private int size;
12    private String brand;
13 
14    public HDTV(int size, String brand) {
15        this.size = size;
16        this.brand = brand;
17    }
18 
19    public int getSize() {
20        return size;
21    }
22 
23    public void setSize(int size) {
24        this.size = size;
25    }
26 
27    public String getBrand() {
28        return brand;
29    }
30 
31    public void setBrand(String brand) {
32        this.brand = brand;
33    }
34}
35 
36 
37package com.diguage.books.simplejava.ar14.comparator;
38 
39import java.util.Comparator;
40 
41/**
42 * Comparator使用示例
43 * <p/>
44 * Coder:D瓜哥,http://www.diguage.com/
45 * <p/>
46 * Date: 2014-11-03 19:10
47 */
48public class SizeComparator implements Comparator<HDTV> {
49    @Override
50    public int compare(HDTV tv1, HDTV tv2) {
51        int tv1Size = tv1.getSize();
52        int tv2Size = tv2.getSize();
53        if (tv1Size > tv2Size) {
54            return 1;
55        } else if (tv1Size < tv2Size) {
56            return -1;
57        } else {
58            return 0;
59        }
60    }
61}
62 
63 
64package com.diguage.books.simplejava.ar14.comparator;
65 
66import java.util.ArrayList;
67import java.util.Collections;
68import java.util.List;
69 
70/**
71 * Comparator示例主类
72 * <p/>
73 * Coder:D瓜哥,http://www.diguage.com/
74 * <p/>
75 * Date: 2014-11-03 18:34
76 */
77public class Main {
78    public static void main(String[] args) {
79        HDTV tv1 = new HDTV(55, "Samsung");
80        HDTV tv2 = new HDTV(60, "Sony");
81        HDTV tv3 = new HDTV(42, "Panasonic");
82        List<HDTV> tvs = new ArrayList<HDTV>();
83        tvs.add(tv1);
84        tvs.add(tv2);
85        tvs.add(tv3);
86        Collections.sort(tvs, new SizeComparator());
87        for (HDTV hdtv : tvs) {
88            System.out.println(hdtv.getBrand());
89        }
90    }
91}

运行改程序,输入如下:

1Panasonic
2Samsung
3Sony

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

01package com.diguage.books.simplejava.ar14;
02 
03import java.util.*;
04 
05/**
06 * Collections.reverseOrder()和Comparator的搭配使用。
07 * <p/>
08 * Coder:D瓜哥,http://www.diguage.com/
09 * <p/>
10 * Date: 2014-11-08 23:19
11 */
12public class CollectionsTestMain {
13    public static void main(String[] args) {
14        List<Integer> list = new ArrayList<Integer>();
15        list.add(3);
16        list.add(1);
17        list.add(2);
18        System.out.println(list);
19 
20        Collections.sort(list);
21        System.out.println(list);
22 
23        Comparator<Integer> comparator = Collections.reverseOrder();
24        Collections.sort(list, comparator);
25        System.out.println(list);
26    }
27}

运行该程序,输入如下:

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

3、如何选择呢?

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

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

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

方式一:TreeSetComparator比较器)

01package com.diguage.books.simplejava.ar14.treesetcomparator;
02 
03/**
04 * Dog
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-03 19:40
09 */
10public class Dog {
11    int size;
12 
13    public Dog(int size) {
14        this.size = size;
15    }
16 
17    @Override
18    public String toString() {
19        return "Dog{" +
20                "size=" + size +
21                '}';
22    }
23}
24 
25 
26package com.diguage.books.simplejava.ar14.treesetcomparator;
27 
28import java.util.Comparator;
29 
30/**
31 * Dog的比较器
32 * <p/>
33 * Coder:D瓜哥,http://www.diguage.com/
34 * <p/>
35 * Date: 2014-11-09 08:33
36 */
37public class SizeComparator implements Comparator<Dog> {
38    @Override
39    public int compare(Dog d1, Dog d2) {
40        return d1.size - d2.size;
41    }
42}
43 
44 
45package com.diguage.books.simplejava.ar14.treesetcomparator;
46 
47import java.util.TreeSet;
48 
49/**
50 * Comparator示例主类
51 * <p/>
52 * Coder:D瓜哥,http://www.diguage.com/
53 * <p/>
54 * Date: 2014-11-09 08:35
55 */
56public class ImpComparableMain {
57    public static void main(String[] args) {
58        TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // 传入比较器
59        d.add(new Dog(2));
60        d.add(new Dog(1));
61        d.add(new Dog(3));
62        System.out.println(d);
63    }
64}

方式二:实现Comparable

01package com.diguage.books.simplejava.ar14.treesetcomparable;
02 
03/**
04 * Dog类
05 * <p/>
06 * Coder:D瓜哥,http://www.diguage.com/
07 * <p/>
08 * Date: 2014-11-09 08:41
09 */
10public class Dog implements Comparable<Dog> {
11    int size;
12 
13    public Dog(int size) {
14        this.size = size;
15    }
16 
17    @Override
18    public int compareTo(Dog o) {
19        return o.size - this.size;
20    }
21 
22    @Override
23    public String toString() {
24        return "Dog{" +
25                "size=" + size +
26                '}';
27    }
28}
29 
30 
31package com.diguage.books.simplejava.ar14.treesetcomparable;
32 
33import java.util.TreeSet;
34 
35/**
36 * Comparable示例主类
37 * <p/>
38 * Coder:D瓜哥,http://www.diguage.com/
39 * <p/>
40 * Date: 2014-11-09 08:43
41 */
42public class ImpComparableMain {
43    public static void main(String[] args) {
44        TreeSet<Dog> d = new TreeSet<Dog>();
45        d.add(new Dog(1));
46        d.add(new Dog(2));
47        d.add(new Dog(3));
48 
49        System.out.println(d);
50    }
51}

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



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

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