您的位置:首页 > 编程语言 > Java开发

Java中Comparable和Comparator区别

2017-03-10 19:01 369 查看

Comparable

只有一个方法

public int compareTo(T o);


compareTo方法的返回值是int,有三种情况:

1、比较者(调用compareTo方法者)大于被比较者(也就是compareTo方法接受对象),那么返回 1

2、比较者等于被比较者,那么返回0

3、比较者小于被比较者,那么返回 -1

Comparable可以认为是一个内比较器,很多类都会实现这个接口以提供对该类对象之间比较的默认实现;比如String,Integer,Float,Double类都实现了Comparable接口。实现Comparable接口的类有一个特点,就是这些类提供了自己对象之间比较大小的默认实现,如果开发者add进入一个Collection的对象想要通过Collections的sort方法帮你自动进行排序的话,那么这个add进入的对象类必须实现Comparable接口。

package org.vincent.strategy.test;

/**
* 实现一个类如果需要实现比较大小,那么继承Comparable接口,泛型参数T 是比较谁就写谁
*
* @ClassName: Domain
* @Description: TODO(这里用一句话描述这个类的作用)
* @author PengRong
* @date 2017年3月10日 下午6:41:54
*/
public class Domain implements Comparable<Domain> {

private String string;

public String getString() {
return this.string;
}

public void setString(String string) {
this.string = string;
}

public Domain(String name) {
this.string = name;
}

public int compareTo(Domain o) {
// TODO Auto-generated method stub
if (this.string.compareTo(o.getString()) > 0)
return 1;
else if (this.string.compareTo(o.getString()) == 0)
return 0;
else
return -1;
}

}


测试代码:

package org.vincent.strategy.test;

public class Test {
public static void main(String[] args) {
Domain d1 = new Domain("c");
Domain d2 = new Domain("c");
Domain d3 = new Domain("b");
Domain d4 = new Domain("d");
System.out.println(d1.compareTo(d2));
System.out.println(d1.compareTo(d3));
System.out.println(d1.compareTo(d4));
}
}


输出:

0
1
-1


实现Comparable接口的类是为了支持类对象之间是可以比较的,但是其实代码里面Comparable的泛型未必就一定要是Domain,将泛型指定为String或者指定为其他任何任何类型都可以—-只要我们知道具体的比较类型就行。

比如讲Comparable的泛型参数指定为String,相应compareTo函数变为:

public int compareTo(String o) {
// TODO Auto-generated method stub
if (this.string.compareTo(o) > 0)
return 1;
else if (this.string.compareTo(o) == 0)
return 0;
else
return -1;
}


但是一般我们不这样做,泛型参数直接为我们定义的类Domain

总结:Comparable接口就是用于给类提供默认比较功能的。

Comparator

Comparator可以认为是是一个外比较器,认为有两种情况可以使用实现Comparator接口的方式:

一个对象不支持自己和自己比较(没有实现Comparable接口),但是又想对两个对象进行比较;一般同类型对象比较很少实现这个接口。

一个对象实现了Comparable接口,但是开发者认为compareTo方法中的比较方式并不是自己想要的那种比较方式。Comparator接口更多是实现这个功能。对特定比较需求提供支持。

int compare(T o1, T o2);


Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种情况:

1、o1大于o2,返回1

2、o1等于o2,返回0

3、o1小于o3,返回-1

实例:

package org.vincent.strategy;

import java.util.Comparator;

/**
* 定义一个按照绝对值排序的比较器
*
* @ClassName: AbsComparator
* @Description: TODO(这里用一句话描述这个类的作用)
* @author PengRong
* @date 2017年3月10日 下午6:06:41
*/
public class AbsComparator implements Comparator {
public int compare(Object o1, Object o2) {
int v1 = Math.abs(((Integer) o1).intValue());
int v2 = Math.abs(((Integer) o2).intValue());
return v1 > v2 ? 1 : (v1 == v2 ? 0 : -1);
}
}


测试:

package org.vincent.strategy;

import java.util.Arrays;
import java.util.Random;

public class Test {
@SuppressWarnings("unchecked")
public static void main(String[] args) {

// 产生一个20个随机整数的数组(有正有负)
Random rnd = new Random();
Integer[] integers = new Integer[20];
for (int i = 0; i < integers.length; i++) {
integers[i] = new Integer(rnd.nextInt(100) * (rnd.nextBoolean() ? 1 : -1));
}

System.out.println("用Integer内置方法排序:也就是Integer实现Comparable接口所描述的比较方法");
Arrays.sort(integers);
System.out.println(Arrays.asList(integers));

System.out.println("用AbsComparator排序:按绝对值大小排序");
Arrays.sort(integers, new AbsComparator());
System.out.println(Arrays.asList(integers));
}
}


输出结果:

用Integer内置方法排序:也就是Integer实现Comparable接口所描述的比较方法
[-88, -82, -82, -78, -70, -70, -58, -58, -48, -48, -46, -35, -10, 4, 7, 19, 39, 45, 53, 85]
用AbsComparator排序:按绝对值大小排序
[4, 7, -10, 19, -35, 39, 45, -46, -48, -48, 53, -58, -58, -70, -70, -78, -82, -82, 85, -88]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: