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

Java中Comparable与Comparator的区别

2016-12-10 10:10 316 查看


Comparable 简介

Comparable 是排序接口。在java.lang包下

若一个类实现了Comparable接口,就意味着“该类支持排序”。 即然实现Comparable接口的类支持排序,假设现在存在“实现Comparable接口的类的对象的List列表(或数组)”,则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序。

此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。


Comparable 定义

Comparable 接口仅仅只包括一个函数,它的定义如下:
package java.lang;
import java.util.*;

public interface Comparable<T>
{
public int compareTo(T o);
}


说明: 
假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。


Comparator 简介

Comparator 是比较器接口。在java.util包下

我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现Comparator接口即可。

也就是说,我们可以通过“实现Comparator类来新建一个比较器”,然后通过该比较器对类进行排序。


Comparator 定义

Comparator 接口仅仅只包括两个个函数,它的定义如下:

package java.util;

public interface Comparator<T>
{

int compare(T o1, T o2);

boolean equals(Object obj);
}



Comparator 和 Comparable 比较

Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。 

而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。

我们不难发现:Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。

代码演示:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
/**
* <em>测试类</em>
* @author StormMaybin
*/
public class ComparatorAndComparableDemo
{

publ
d9fd
ic static void main(String[] args)
{
//定义一个ArrayList容器
ArrayList<Person> persons = new ArrayList<Person>();
String [] names = {"StormMa", "Jack", "Rose", "Mary"};
int [] ages = {20, 21, 21, 18};
for (int i = 0; i < 4; i++)
persons.add(new Person(names[i], ages[i]));

//排序之前
System.out.println("排序之前: "+persons);

//按照Person类中实现Comparable接口的规则排序。这里的规则是按照姓名排序
Collections.sort(persons);
System.out.println("按照姓名排序: "+persons);

//通过AscAgeComparator比较器进行排序,即按照年龄升序排列
Collections.sort(persons, new AscAgeComparator());
System.out.println("按照年龄升序排序"+persons);

//通过DscAgeComparator比较器进行排序,即按照年龄降序排列
Collections.sort(persons, new DscAgeComparator());
System.out.println("按照年龄降序排序"+persons);

//通过AscAgeAscNameComparator比较器进行排序
//即按照首先按照年龄升序,年龄相同的情况下,
//按照姓名升序排列
Collections.sort(persons, new AscAgeAscNameComparator());
System.out.println("按照年龄和姓名升序排列: "+persons);
}
}

/**
* <em>Person类实现Comparable,按姓名升序排列</em>
* @author StormMaybin
*/
class Person implements Comparable<Person>
{
private String name;
private int age;
//Constructor
public Person (String name, int age)
{
this.name = name;
this.age = age;
}
/**
* 比较两个Person是否相等:若它们的name和age都相等,则认为它们相等
*/
boolean equals(Person o)
{
if (this.age == o.age && this.name == o.name)
return true;
return false;
}
/**
* 实现Comparable接口,这里只针对姓名进行排序
*/
@Override
public int compareTo(Person o)
{
// TODO Auto-generated method stub
return this.name.compareTo(o.name);
}
@Override
public String toString()
{
// TODO Auto-generated method stub
return "( name: " + name +","+ "age: "+age+")";
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
}

/**
* <em>定义AscAgeComparator比较器实现Comparator接口
* 对Person类的age属性进行升序排列</em>
* @author StormMaybin
*/
class AscAgeComparator implements Comparator<Person>
{

@Override
public int compare(Person o1, Person o2)
{
// TODO Auto-generated method stub
return o1.getAge() - o2.getAge();
}
}

/**
* <em>定义DscAgeComparator比较器实现Comparator接口
* 对Person类的age属性进行降序排列</em>
* @author StormMaybin
*/
class DscAgeComparator implements Comparator<Person>
{

@Override
public int compare(Person o1, Person o2)
{
// TODO Auto-generated method stub
return -(o1.getAge() - o2.getAge());
}
}
/**
* <em>定义AscAgeAscNameComparator比较器实现Comparator接口
* 对Person类的age name 属性升序排列</em>
* @author StormMaybin
*/
class AscAgeAscNameComparator implements Comparator<Person>
{

@Override
public int compare(Person o1, Person o2)
{
// TODO Auto-generated method stub
if (o1.getAge() == o2.getAge())
return o1.getName().compareTo(o2.getName());
else
return o1.getAge() - o2.getAge();
}
}


运行结果:

总结:

Java 中的两种排序方式:
Comparable 自然排序。(实体类实现)
Comparator 是定制排序。(无法修改实体类时,直接在调用方创建)

同时存在时采用 Comparator(定制排序)的规则进行比较。

对于一些普通的数据类型(比如 String, Integer, Double…),它们默认实现了Comparable 接口,实现了 compareTo 方法,我们可以直接使用。

而对于一些自定义类,它们可能在不同情况下需要实现不同的比较策略,我们可以新创建 Comparator 接口,然后使用特定的 Comparator 实现进行比较。

换句话说,Comparable是让一个实体类具有排序的能力,而Comparator充当一个比较器的作用,不同实体类排序可以依据同一个比较器。

这就是 Comparable 和 Comparator 的区别。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: