说说Java的Comparable 与 Comparator
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);
}
}