Comparable & Comparator 都是用来实现集合中元素的比较、排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序,所以,如想实现排序,就需要在集合外定义 Comparator 接口的方法或在集合内实现 Comparable 接口的方法。

Comparator位于包java.util下,而Comparable位于包   java.lang下

Comparable 是一个对象本身就已经支持自比较所需要实现的接口(如 String、Integer 自己就可以完成比较大小操作,已经实现了Comparable接口)

自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,如API所说:
Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface
这里的自然顺序就是实现Comparable接口设定的排序方式。

而 Comparator 是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。
  
可以说一个是自已完成比较,一个是外部程序实现比较的差别而已。

用 Comparator 是策略模式(strategy design pattern),就是不改变对象自身,而用一个策略对象(strategy object)来改变它的行为。
  
比如:你想对整数采用绝对值大小来排序,Integer 是不符合要求的,你不需要去修改 Integer 类(实际上你也不能这么做)去改变它的排序行为,只要使用一个实现了 Comparator 接口的对象来实现控制它的排序就行了。

// AbsComparator.java     
import   java.util.*;

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);     
    }     
}

可以用下面这个类测试 AbsComparator:

// Test.java     
import   java.util.*;

public   class   Test   {     
    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内置方法排序:");     
      Arrays.sort(integers);     
      System.out.println(Arrays.asList(integers));     
    
      System.out.println("用AbsComparator排序:");     
      Arrays.sort(integers,   new   AbsComparator());     
      System.out.println(Arrays.asList(integers));     
    }     
}

Collections.sort((List<T> list, Comparator<? super T> c)是用来对list排序的。

如果不是调用sort方法,相要直接比较两个对象的大小,如下:
Comparator定义了俩个方法,分别是   int   compare(T   o1,   T   o2)和   boolean   equals(Object   obj),
用于比较两个Comparator是否相等
true only if the specified object is also a comparator and it imposes the same ordering as this comparator.
有时在实现Comparator接口时,并没有实现equals方法,可程序并没有报错,原因是实现该接口的类也是Object类的子类,而Object类已经实现了equals方法

Comparable接口只提供了   int   compareTo(T   o)方法,也就是说假如我定义了一个Person类,这个类实现了   Comparable接口,那么当我实例化Person类的person1后,我想比较person1和一个现有的Person对象person2的大小时,我就可以这样来调用:person1.comparTo(person2),通过返回值就可以判断了;而此时如果你定义了一个   PersonComparator(实现了Comparator接口)的话,那你就可以这样:PersonComparator   comparator=   new   PersonComparator();
comparator.compare(person1,person2);。

当需要排序的集合或数组不是单纯的数字型时,通常可以使用Comparator或Comparable,以简单的方式实现对象排序或自定义排序。

一、Comparator

强行对某个对象collection进行整体排序的比较函数,可以将Comparator传递给Collections.sort或Arrays.sort。

接口方法:

  /**
   * @return o1小于、等于或大于o2,分别返回负整数、零或正整数。
   */
  int compare(Object o1, Object o2);

案例:

import java.util.Arrays;
import java.util.Comparator;

public class SampleComparator implements Comparator {

public int compare(Object o1, Object o2) {
    return toInt(o1) - toInt(o2);
  }

private int toInt(Object o) {
    String str = (String) o;
    str = str.replaceAll("一", "1");
    str = str.replaceAll("二", "2");
    str = str.replaceAll("三", "3");
    // 
    return Integer.parseInt(str);
  }

/**
   * 测试方法
   */
  public static void main(String[] args) {
    String[] array = new String[] { "一二", "三", "二" };
    Arrays.sort(array, new SampleComparator());
    for (int i = 0; i < array.length; i++) {
      System.out.println(array[i]);
    }
  }

}

二、Comparable

强行对实现它的每个类的对象进行整体排序,实现此接口的对象列表(和数组)可以通过Collections.sort或Arrays.sort进行自动排序。

接口方法:

  /**
   * @return 该对象小于、等于或大于指定对象o,分别返回负整数、零或正整数。 
   */
  int compareTo(Object o);

假设对象User,需要按年龄排序:

public class User {

private String id;
  private int age;

public User(String id, int age) {
    this.id = id;
    this.age = age;
  }

public int getAge() {
    return age;
  }

public void setAge(int age) {
    this.age = age;
  }

public String getId() {
    return id;
  }

public void setId(String id) {
    this.id = id;
  }

}

改造后的对象:

import java.util.Arrays;

public class User implements Comparable {

private String id;
  private int age;

public User(String id, int age) {
    this.id = id;
    this.age = age;
  }

public int getAge() {
    return age;
  }

public void setAge(int age) {
    this.age = age;
  }

public String getId() {
    return id;
  }

public void setId(String id) {
    this.id = id;
  }

public int compareTo(Object o) {
    return this.age - ((User) o).getAge();
  }

/**
   * 测试方法
   */
  public static void main(String[] args) {
    User[] users = new User[] { new User("a", 30), new User("b", 20) };
    Arrays.sort(users);
    for (int i = 0; i < users.length; i++) {
      User user = users[i];
      System.out.println(user.getId() + " " + user.getAge());
    }
  }

}

三、Comparator和Comparable的区别

先看一下使用Comparator对User集合实现排序的方式:

import java.util.Arrays;
import java.util.Comparator;

public class UserComparator implements Comparator {

public int compare(Object o1, Object o2) {
    return ((User) o1).getAge() - ((User) o2).getAge();
  }

/**
   * 测试方法
   */
  public static void main(String[] args) {
    User[] users = new User[] { new User("a", 30), new User("b", 20) };
    Arrays.sort(users, new UserComparator());
    for (int i = 0; i < users.length; i++) {
      User user = users[i];
      System.out.println(user.getId() + " " + user.getAge());
    }
  }

}

一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序。
Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
1、类的设计师没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身
2、可以使用多种排序标准,比如升序、降序等

Comparable & Comparator的更多相关文章

  1. 【集合框架】JDK1.8源码分析之Comparable && Comparator(九)

    一.前言 在Java集合框架里面,各种集合的操作很大程度上都离不开Comparable和Comparator,虽然它们与集合没有显示的关系,但是它们只有在集合里面的时候才能发挥最大的威力.下面是开始我 ...

  2. 给jdk写注释系列之jdk1.6容器(9)-Strategy设计模式之Comparable&Comparator接口

    前面我们说TreeMap和TreeSet都是有顺序的集合,而顺序的维持是要靠一个比较器Comparator或者map的key实现Comparable接口.      既然说到排序,首先我们不用去关心什 ...

  3. Java学习笔记--集合元素的比较Comparable,Comparator

    原文见: http://www.cnblogs.com/sunflower627/p/3158042.html 1. Comparator 和 Comparable 相同的地方 他们都是java的一个 ...

  4. Iterator & Iterable 和 Comparable&Comparator

    java.lang.Iterator & java.lang.Iterable Iterator和Iterable的区别和联系 iterator是具有迭代状态的对象.它允许你检查它是否有更多的 ...

  5. Java提高十五:容器元素比较Comparable&Comparator深入分析

    我们经常用容器来存放元素,通常而言我们是不关系容器中的元素是否有序,但有些场景可能要求容器中的元素是有序的,这个时候用ArrayList  LinkedList  Hashtable HashMap ...

  6. Java容器解析系列(8) Comparable Comparator

    Comparable和Comparator接口是两个用于对对象进行大小比较的接口,在java集合相关类中,也被经常地使用到. 关于其使用,可以参考网络上的其他博客(没什么好说的);这里阐述关于这两个接 ...

  7. JDK1.8源码分析之Comparable && Comparator

    import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util. ...

  8. java容器---Comparable & Comparator

    1.接口Comparable<T> API    参数类型:T ---可以与此对象进行比较的那些对象的类型 此接口强行对实现它的每个类的对象进行整体排序.这种排序被称为类的自然排序,类的c ...

  9. 比较器Comparable Comparator

    一. Comparable Comparable 是排序接口,若一个类实现了 Comparable 接口,就意味着该类支持排序.实现了Comparable 接口的类的对象的列表或者数组可以通过 Col ...

随机推荐

  1. GDAL Configure in Visual Studio 2010 for Win7/ GDAL+VisualStudio2010 Win7 配置

    配置环境: OS:Win& *86 Ultimate Edition(EN) VS:Visual Studio 2010(EN) Step1: GDAL源码下载:http://www.gisi ...

  2. UILabel常用属性

    [super viewDidLoad]; // 实例化UILabel并指定其边框 UILabel *label = [[UILabel alloc]initWithFrame:CGRectMake(0 ...

  3. 抽象类(abstract)是否可以继承自实体类 ?

    可以. 但是这个实体类必须有无参构造函数(默认的构造函数). 如: public class A { //这个构造函数必须要有(在没有构造函数重载时可以省略,因为运行时会为A添加默认构造函数) pub ...

  4. sql临时表和表变量

    1. 为什么要使用表变量 表变量是从2000开始引入的,微软认为与本地临时表相比,表变量具有如下优点:  a.与其他变量的定义一样,表变量具有良好的定义范围,并会被自动清除:  b.在存储过程中使用表 ...

  5. jasonTree多选多级树控件

    jasonTree1.0 jasonTree多选多级树控件(名字是自己取),用于友好的展示树形结构的数据,并可以多选,传统的做法是在一个select的下拉框中显示一个可折叠的树结构,公司的需求人员这种 ...

  6. emmet(Zen coding)帮助文档

    葵花宝典终可成,半途而废万事空. 官方地址:http://docs.emmet.io/cheat-sheet/ 我导出了pdf版,需要的同学可以下载: 链接:http://pan.baidu.com/ ...

  7. Discuz 3.X 门户文章插入图片自动添加 alt 标签

    最近用 Discuz 搭建了个网站--儿童安全座椅网(www.bbseat.com.cn),用到了门户功能,不得不说Discuz 的功能还是非常强大的,但在使用过程中发现在发表文章时添加了图片却不能像 ...

  8. 利用Unicode属性移除文本中的标点符号

    原文:http://bbs.csdn.net/topics/270033191   摘抄: str = str.replaceAll("[\\pP‘’“”]", "&qu ...

  9. How to: Enable and Disable an Action Pane Button on a List Page [AX 2012]

    Applies To: Microsoft Dynamics AX 2012 R2, Microsoft Dynamics AX 2012 Feature Pack, Microsoft Dynami ...

  10. Spark 大数据平台

    Apache Spark is an open source cluster computing system that aims to make data analytics fast - both ...