Comparable和Comparator的区别

     英文原文地址:http://www.programcreek.com/2011/12/examples-to-demonstrate-comparable-vs-comparator-in-java/

   Comparable 和Comparator是JAVA核心API中的两个接口。从他们的名字我们可以看出,这两个接口都是用于对象的比较。但是,他们到底是什么以及他们之间有什么区别?下面举了两个例子来回答这些问题,在看过这些例子后,你将学会如何使用Comparable和Comparator。

1. Comparable

    如果一个类需要比较当前实例和其他对象,则需要实现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.");
		}
	}
}
     运行结果是:Sony is better.

2. Comparator

     在某些情况下,你也许不想因为想要对象是可比较的,就改变类的内部结构。在这种情况下,Comparator就可以用来比较对象了,例如,2个人可以根据“身高”或者是“年龄”来进行比较。(这可以使用Comparable来实现。)

    这个方法要求实现compare()。现在,让我们使用另一种方法来比较TV(基于TV的大小)。使用Comparator的共同点就是排序。Collections和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()方法来获取一个降序排序的Comparator,就如下面所示:

  

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) 它可能会作为参数,传输给如Collection.sort()或者Arrays.sort()等排序方法;

    (2) 这也被应用到特定的数据结构上,以控制该数据结构的顺序,例如有序集合(例如TreeSet)或者有序map(例如TreeMap)。

    例如,创造一个TreeSet,我们可以把其构造函数传输给comparator,或者直接使得其对象是可以comparable的。

    方法一(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));
	}
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值