2.1. Comparable vs. Comparator

Comparable 和 Comparator 是Java核心API提供的两个接口,通过它们的名字,我们可以说它们也许用来通过某种方式来进行比较。但是准确来说它们是什么,它们之间有什么区别那。下面的两个例子来回答这个问题。下面的例子比较了HDTV的大小,如何用它们,读完代码后会有明确的认识。

1.Comparable

Comparable 被类实现,用来比较这个类的两个对象。类必须实现这个接口,才能在它的对象间进行比较。需要实现的方法是compareTo().下面是例子:

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;
    }
}
 
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.");
        }
    }
}

2. Comparator

在某些条件下,你也许想不改变类的情况下使它具有可比较性。 在这种情况下。Comparator 可以被用做基于对象的特定属性和字段进行比较。举个例子,两个人可以通过‘身高’或‘年龄’进行比较等。

需要实现的方法是compare()。现在我们用另外一种方式通过Size来比较HDTV。一个Comparator最通常的做法是排序。无论是Collection还是Arrays类都用Comparator来提供一个排序的方法。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
 
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;
    }
}
 
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;
        }
    }
}
 
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");
 
        ArrayList<HDTV> al = new ArrayList<HDTV>();
        al.add(tv1);
        al.add(tv2);
        al.add(tv3);
 
        Collections.sort(al, new SizeComparator());
        for (HDTV a : al) {
            System.out.println(a.getBrand());
        }
    }
}

输出:
···
Panasonic
Samsung
Sony
···
另外我们常用Collections.reverseOrder()方法来获得一个倒序的比较器,如下:

ArrayList<Integer> al = new ArrayList<Integer>();
al.add(3);
al.add(1);
al.add(2);
System.out.println(al);
Collections.sort(al);
System.out.println(al);
 
Comparator<Integer> comparator = Collections.reverseOrder();
Collections.sort(al,comparator);
System.out.println(al);

输出:

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

3. 如何使用

简单来说,一个实现Comparable的类将是可比较的,这意味着它的对象可以相互比较。

一个实现Comparator经常用在两个情景:
1)它常被传递给一个排序方法,比如Collections.sort()或者Arrays.sort(),以在排序中进行精确控制。
2)它也常用来控制特定数据结构的顺序,比如一个排序的sets(例如TreeSet)或者排序的map(例如TreeMap)

举个例子,在创建TreeSet ,我们可以创建一个可比较对象或者传递一个comparator的构造。

方法一1 -TreeSet(Comparator comparator)

class Dog {
    int size;
 
    Dog(int s) {
        size = s;
    }
}
 
class SizeComparator implements Comparator<Dog> {
    @Override
    public int compare(Dog d1, Dog d2) {
        return d1.size - d2.size;
    }
}
 
public class ImpComparable {
    public static void main(String[] args) {
        TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator()); // pass comparator
        d.add(new Dog(1));
        d.add(new Dog(2));
        d.add(new Dog(1));
    }
}

方法二,实现Comparable

class Dog implements Comparable<Dog>{
    int size;
 
    Dog(int s) {
        size = s;
    }
 
    @Override
    public int compareTo(Dog o) {
        return o.size - this.size;
    }
}
 
public class ImpComparable {
    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(1));
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 从三月份找实习到现在,面了一些公司,挂了不少,但最终还是拿到小米、百度、阿里、京东、新浪、CVTE、乐视家的研发岗...
    时芥蓝阅读 42,475评论 11 349
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 32,256评论 18 399
  • 1.import static是Java 5增加的功能,就是将Import类中的静态方法,可以作为本类的静态方法来...
    XLsn0w阅读 5,030评论 0 2
  • 面向对象主要针对面向过程。 面向过程的基本单元是函数。 什么是对象:EVERYTHING IS OBJECT(万物...
    sinpi阅读 4,791评论 0 4
  • —我没心 我:那你的心在哪? —一出生就没了 我:我有,我分你一半 —你那么花心啊? 我:我只有一颗心 —… 我:...
    流水依旧只东去阅读 2,744评论 0 0

友情链接更多精彩内容