杰 & C++ & Python & DM

Java Comparator和Comparabler的区别

  新接触java没多久,前几天用到排序的问题,看到Comparator和Comparable两个接口类有点迷惑,研究了两天也没理解有什么区别,今天在看《Java核心编程》时,才恍然大悟。在这里表达一下自己的想法。
  当需要排序的集合或数组时可以使用Comparator或Comparable,它们都可以实现排序,但是它们的区别是Comparator从外部定义了对象的比较规则,而Comparable则是从内部定义了对象是可比较的。下面将详细解这句话。

一、 Comparator
  Comparator从外部定义了对象的比较规则
  比如,你要使用某人写的一个矩形类Rect。现在你有一个Rect的集合(或数组),你想实现对Rect的排序,现在有一个问题,某人在实现Rect的时候没有考虑到会有人将会比较Rect对象。这个时候你必须根据需要对Rect进行排序(比如,根据矩形的长进行排序),在这个场景下使用Comparator,因为Rect类已经存在,你不能对其进行改变。

import java.util.*;

public class Rectangle {
    
    
public static void main(String[] args)
    {
        Rect[] rectArrays 
= new Rect[] {new Rect(34), new Rect(52), new Rect(45)};
        
        
// 排序,将定义的RectComparator作为参数
        Arrays.sort(rectArrays, new RectComparator());
        
        
for (int i=0; i != rectArrays.length; ++i)
            System.out.println(rectArrays[i]);
    }
    
    
// 定义一个Rect比较方式:根据Rect的长比较
    public static class RectComparator implements Comparator<Rect>
    {
        
public int compare(Rect o1, Rect o2)
        {
            
return o1.getLength() - o2.getLength();
        }
    }

    
public static class Rect
    {
        Rect(
int l, int w)
        {
            
this.length = l;
            
this.width = w;
        }
        
        
public int getLength()
        {
            
return this.length;
        }
        
        
public int getWidth()
        {
            
return this.width;
        }
        
        
public int getArea()
        {
            
return this.length * this.width;
        }
        
        
public String toString()
        {
            
return "length: " + length + " width: " + width;
        }
        
        
private int length;
        
private int width;
    }
}

输出:
length: 3 width: 4
length: 4 width: 5
length: 5 width: 2


二、 Comparable
  Comparable则是从内部定义了对象的是可比较的
  还是以Rect为例,假如你是Rect的实现者,在你定义Rect时,你觉得有必要定义一个比较方式,这个时候就应该使Rect继承Comparable接口。如果你觉得较合理的排序方式是根据Rect的面积进行排序,那么可以这样实现

import java.util.*;

public class Rectangle {
    
    
public static void main(String[] args)
    {
        Rect[] rectArrays 
= new Rect[] {new Rect(34), new Rect(52), new Rect(45)};
        
        Arrays.sort(rectArrays);
        
        
for (int i=0; i != rectArrays.length; ++i)
            System.out.println(rectArrays[i]);
    }

    
// 定义了Comparable接口
    public static class Rect implements Comparable<Rect>
    {
        Rect(
int l, int w)
        {
            
this.length = l;
            
this.width = w;
        }
        
        
public int getLength()
        {
            
return this.length;
        }
        
        
public int getWidth()
        {
            
return this.width;
        }
        
        
public int getArea()
        {
            
return this.length * this.width;
        }
        
        
public String toString()
        {
            
return "length: " + length + " width: " + width;
        }
        
        
// 重载compareTo函数,按面积比较
        @Override
        
public int compareTo(Rect that)
        {
            
return this.getArea() - that.getArea();
        }
        
        
private int length;
        
private int width;
    }
}
输出:
length: 5 width: 2
length: 3 width: 4
length: 4 width: 5

三、总结
通过Comparator和Comparable的意思我们也可以看出两者的区别
Comparable意为“可比较的”,一个类继承了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序。
Comparator意为“比较算子”,因此Comparator可以看成一种算法的实现,将算法和数据分离。

  另外,通过定义方式,我们可以发现如果一个类继承了Comparable接口,则表明这个类的对象之间是可以比较的,且比较的方式只有一种。但是Comparator可以定义多种比较方式。在第二个程序中,Rect定义了按面积进行比较,如果我们想按长对Rect进行排序,那么也可以通过Comparator来实现。

  最后,再次强调Comparator从外部定义了对象的比较规则,而Comparable则是从内部定义了对象是可比较的


参考资料
http://www.blogjava.net/fastunit/archive/2008/04/08/191533.html
《Java核心编程》第7版,p91-p92





posted on 2012-04-11 16:04 jaysoon 阅读(1168) 评论(0)  编辑 收藏 引用 所属分类: Java


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2024年5月>
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678

导航

统计

常用链接

留言簿

随笔分类

随笔档案

文章分类

文章档案

收藏夹

C++

搜索

最新评论

阅读排行榜

评论排行榜