说说Java的Comparable 与 Comparator

白玉 IT哈哈 Comparable和Comparator是Java核心API提供的两个接口。从它们的名字就可以看出,他们用于比较对象的大小。接下来的两个例子来回答这个问题。这个简单的例子就是比较两种HaHa的尺寸。当阅读完下面的代码,你就知道如何使用Comparable和Comparator。

1、Comparable

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


package com.demo;
public class HaHa implements Comparable<HaHa>{
	private int size;
	private String brand;
	public HaHa(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(HaHa ha) {
		if (this.getSize() > ha.getSize()) {
			return 1;
		} else if (this.getSize() < ha.getSize()) {
			return -1;
		} else {
			return 0;
		}
	}
}

package com.demo;
public class Main {
	public static void main(String[] args) {
		HaHa ha1 = new HaHa(55, "Samsung");
		HaHa ha2 = new HaHa(60, "Sony");
		if (ha1.compareTo(ha2) > 0) {
			System.out.println(ha1.getBrand() + " is better.");
		} else {
			System.out.println(ha2.getBrand() + " is better.");
		}
	}
}

运行该程序,输入如下: Sony is better.

2、Comparator

对于比较对象间的不同属性,Comparator能更好的胜任。例如,两个人可以基于name和age进行比较等。(这些情况,Comparable就不可以胜任了。) 必须实现compare()方法。现在,让我们使用其他方式来比较这些TV的尺寸。Comparator的常用方法是排序。Collections和Arrays类都提供了一个可以使用Comparator的排序方法。例子如下:


package com.demo.Comparator;
public class HaHa{
	private int size;
	private String brand;
	public HaHa(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.demo.Comparator;
import java.util.Comparator;

public class SizeComparator implements Comparator<HaHa>{
	@Override
	public int compare(HaHa o1, HaHa o2) {
		int ha1Size = o1.getSize();
		int ha2Size = o2.getSize();
		if(ha1Size > ha2Size){
			return 1;
		} else if(ha1Size < ha2Size){
			return -1;
		} else{
			return 0;
		}
	}
}
package com.demo.Comparator;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Main {
	public static void main(String[] args) {
		HaHa ha1 = new HaHa(55, "Samsung");
		HaHa ha2 = new HaHa(60, "Sony");
		HaHa ha3 = new HaHa(42, "Panasonic");
		List<HaHa> has = new ArrayList<HaHa>();
		has.add(ha1);
		has.add(ha2);
		has.add(ha3);
		Collections.sort(has, new SizeComparator());
		for (HaHa ha : has) {
			System.out.println(ha.getBrand());
		}
	}
}

运行改程序,输入如下: Panasonic Samsung Sony

3、如何选择呢

简单来说,一个实现Comparable接口的类具有可比性,意思就是说它的实例相互直接可以进行比较。 一个实现Comparator接口的类就一个比较器(Comparator),相对于其他类。首先,它可以被传入排序方法,例如Collections.sort()或Arrays.sort(),可精确控制排序顺序;其次,它还可以被用于控制已有的某行数据结构的顺序,例如排序的set或排序的map。 例如,创建TreeSet,我们可以在构造函数中传入一个Comparator,或者将一个类添加可比性。

方式一:TreeSet(Comparator比较器)


package com.demo.treesetcomparator;
public class Dog {
	 int size;
	 public Dog(int size){
		 this.size = size;
	 }
	@Override
	public String toString(){
		return "Dog{size="+size+"}";
	}
}
package com.demo.treesetcomparator;
import java.util.Comparator;
public class SizeComparator implements Comparator<Dog>{
	@Override
	public int compare(Dog o1, Dog o2) {
		return o1.size - o2.size;
	}
}
package com.demo.treesetcomparator;
import java.util.TreeSet;
public class ImpComparableMain {
	public static void main(String[] args) {
		TreeSet<Dog> d = new TreeSet<Dog>(new SizeComparator());
		d.add(new Dog(3));
		d.add(new Dog(1));
		d.add(new Dog(2));
		System.out.println(d);
	}
}

方式二:实现Comparable


package com.demo.treesetcomparable;
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.demo.treesetcomparable;
import java.util.TreeSet;
import com.demo.treesetcomparable.Dog;
public class ImpComparableMain {
	public static void main(String[] args) {
		TreeSet<Dog> d = new TreeSet<Dog>();
		d.add(new Dog(3));
		d.add(new Dog(1));
		d.add(new Dog(2));
		System.out.println(d);
	}
}