Comparator和Comparable比较

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

一、Comparator

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

接口方法:

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

案例:

 1import java.util.Arrays;
 2import java.util.Comparator;
 3
 4public class SampleComparator implements Comparator {
 5
 6  public int compare(Object o1, Object o2) {
 7    return toInt(o1) - toInt(o2);
 8  }
 9
10  private int toInt(Object o) {
11    String str = (String) o;
12    str = str.replaceAll("一", "1");
13    str = str.replaceAll("二", "2");
14    str = str.replaceAll("三", "3");
15    return Integer.parseInt(str);
16  }
17
18  /**
19   * 测试方法
20   */
21  public static void main(String[] args) {
22    String[] array = new String[] { "一二", "三", "二" };
23    Arrays.sort(array, new SampleComparator());
24    for (int i = 0; i < array.length; i++) {
25      System.out.println(array[i]);
26    }
27  }
28
29}

二、Comparable

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

接口方法:

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

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

 1public class User {
 2
 3  private String id;
 4  private int age;
 5
 6  public User(String id, int age) {
 7    this.id = id;
 8    this.age = age;
 9  }
10
11  public int getAge() {
12    return age;
13  }
14
15  public void setAge(int age) {
16    this.age = age;
17  }
18
19  public String getId() {
20    return id;
21  }
22
23  public void setId(String id) {
24    this.id = id;
25  }
26
27}

改造后的对象:

 1import java.util.Arrays;
 2
 3public class User implements Comparable {
 4
 5  private String id;
 6  private int age;
 7
 8  public User(String id, int age) {
 9    this.id = id;
10    this.age = age;
11  }
12
13  public int getAge() {
14    return age;
15  }
16
17  public void setAge(int age) {
18    this.age = age;
19  }
20
21  public String getId() {
22    return id;
23  }
24
25  public void setId(String id) {
26    this.id = id;
27  }
28
29  public int compareTo(Object o) {
30    return this.age - ((User) o).getAge();
31  }
32
33  /**
34   * 测试方法
35   */
36  public static void main(String[] args) {
37    User[] users = new User[] { new User("a", 30), new User("b", 20) };
38    Arrays.sort(users);
39    for (int i = 0; i < users.length; i++) {
40      User user = users[i];
41      System.out.println(user.getId() + " " + user.getAge());
42    }
43  }
44
45}

三、Comparator和Comparable的区别

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

 1import java.util.Arrays;
 2import java.util.Comparator;
 3
 4public class UserComparator implements Comparator {
 5
 6  public int compare(Object o1, Object o2) {
 7    return ((User) o1).getAge() - ((User) o2).getAge();
 8  }
 9
10  /**
11   * 测试方法
12   */
13  public static void main(String[] args) {
14    User[] users = new User[] { new User("a", 30), new User("b", 20) };
15    Arrays.sort(users, new UserComparator());
16    for (int i = 0; i < users.length; i++) {
17      User user = users[i];
18      System.out.println(user.getId() + " " + user.getAge());
19    }
20  }
21
22}

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

官方解释:

public interface Comparable<T>

此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序,类的 compareTo 方法被称为它的自然比较方法

实现此接口的对象列表(和数组)可以通过 Collections.sort(和 Arrays.sort)进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。

对于类 C 的每一个 e1 和 e2 来说,当且仅当 (e1.compareTo((Object)e2) == 0) 与 e1.equals((Object)e2) 具有相同的布尔值时,类 C 的自然排序才叫做与 equals 一致。注意,null 不是任何类的实例,即使 e.equals(null) 返回 falsee.compareTo(null) 也会抛出 NullPointerException

强烈推荐(虽然不是必需的)使自然排序与 equals 一致。这是因为在使用其自然排序与 equals 不一致的元素(或键)时,没有显式比较器的有序集合(和有序映射表)行为表现“怪异”。尤其是,这样的有序集合(或有序映射表)违背了根据 equals 方法定义的集合(或映射表)的常规协定。

例如,如果将两个键 a 和 b 添加到一个没有使用显式比较器的有序集合中,使得 (!a.equals((Object)b) && a.compareTo((Object)b) == 0),则第二个 add 操作返回 false(有序集合的大小没有增加),因为从有序集合的角度来看,a 和 b 是等效的。

实际上,所有执行比较的 Java 核心类都具有 equals 一致的自然排序。java.math.BigDecimal 是个例外,它的自然排序把值相等但精确度不同的 BigDecimal 对象(比如 4.0 和 4.00)等同起来。

为了向数学上倾斜,在给定 C 类的基础上定义自然排序的关系 如下:

      {(x, y) such that x.compareTo((Object)y) <= 0}。 

整体排序的 quotient 是:

      {(x, y) such that x.compareTo((Object)y) == 0}。 

它直接遵循 compareTo 的协定,商是 C 的等价关系,自然排序是 C整体排序。当我们说类的自然排序与 equals 一致 时,是指自然排序的商是由类的 equals(Object) 方法定义的等价关系。

    {(x, y) such that x.equals((Object)y)}。
======================================================
public interface Comparator<T>

比较函数强行对某些对象 collection 进行整体排序。可以将 Comparator 传递给 sort 方法(如 Collections.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如 TreeSetTreeMap)的顺序。

当且仅当对于一组元素 S 中的每个 e1e2 而言,(compare((Object)e1, (Object)e2)==0)e1.equals((Object)e2) 具有相等的布尔值时,Comparator c 强行对 S 进行的排序才叫做与等号一致 的排序。

当使用具有与等号一致的强行排序能力的 comparator 对有序 set(或有序映射)进行排序时,应该小心谨慎。假定一个带有显式 Comparator c 的有序 set(或有序映射)与从 set S 中抽取出来的元素(或键)一起使用。如果 c 强行对 S 进行的排序与等号一致,那么有序 set(或有序映射)将是行为“怪异的”。尤其是那些将违背根据 equals 所定义 set(或映射)的常规协定的有序 set(或有序映射)。

例如,如果使用 comparator c 将满足 (a.equals((Object)b) && c.compare((Object)a, (Object)b) != 0) 的两个键 ab 添加到有序 set 中,则第二个 add 操作将返回 false(有序 set 的大小没有增加),因为从有序 set 的角度来看,ab 是相等的。

注:通常用 comparator 来实现 java.io.Serializable 是一个好主意,因为它们在可序列化的数据结构(像 TreeSetTreeMap)中可用作排序方法。为了成功地序列化数据结构,comparator(如果已提供)必须实现 Serializable

在算术上,定义给定 comparator c 对给定对象 set S 强行实施整体排序关系式 为:

       {(x, y) such that c.compare((Object)x, (Object)y) <= 0}. 

整体排序的 是:

       {(x, y) such that c.compare((Object)x, (Object)y) == 0}. 

它直接遵循 compare 的协定,商是 S 上的等价关系,自然顺序是 S 上的整体排序。当我们说 c 强行对 S 的排序是与等号一致 时,意思是说自然排序的商是对象的 equals(Object) 方法所定义的等价关系:

       {(x, y) such that x.equals((Object)y)}.

转自:http://www.blogjava.net/dashi99/archive/2009/02/19/255530.html

转载于:https://www.cnblogs.com/lyhtbc/archive/2012/10/26/Comparator_Comparable.html

Comparator和Comparable (转)相关推荐

  1. Comparator 和 Comparable

    Comparator 和 Comparable 比较 Comparable是排序接口:若一个类实现了Comparable接口,就意味着"该类支持排序". 而Comparator是比 ...

  2. java的Comparator和Comparable

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

  3. Java中Comparator和Comparable之间的区别

    常见的面试问题之一是"比较器和可比较器之间有什么区别". 或"您将如何通过其ID或名称对员工对象集合进行排序".为此,我们可以使用两个接口,即Comparato ...

  4. Java核心技术之Comparator和Comparable在排序中的应用

    自定义的类User: package com.example.testcomparator;public class User{private String name;private int age; ...

  5. Comparator 和 Comparable的使用及区别

    这里写目录标题 Comparable的使用 Comparator比较器 Comparator和Comparable的区别 Comparable的使用 1.1.我们创建一个Student(学生)类 cl ...

  6. Comparator和Comparable的区别

    一.概述   Comparable和Comparator都是两个接口,接口都可以用来实现集合中元素的比较.排序,Comparator位于包java.util下,而Comparable位于包java.l ...

  7. Comparator和Comparable、compare的使用

    比较器排序Comparator和Comparable的使用 简述Comparable和Comparator两个接口的区别. compare是comparator里面的一个方法 Comparable:强 ...

  8. [Java开发之路](21)Comparator与Comparable

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/SunnyYoona/article/details/50889774 1. Comparable p ...

  9. 判断比较器Comparator和Comparable的升序降序问题

    比较器 降序升序问题 Comparator中的compare方法 //升序排序 public int compare(int o1, int o2) {return o1 - o2; }//降序排序 ...

最新文章

  1. 机器学习(MACHINE LEARNING)MATLAB模拟退火算法【SA】
  2. 我的asp.net学习心得
  3. Java实现多线程售票
  4. day15 java的final
  5. Dart教程(二):基本语法
  6. php实现给pdf加水印,pdf文件如何加水印 怎样给pdf文件加水印|帮你轻松实现给pdf加水印...
  7. 思岚A3雷达官方ROS包将雷达的发布频率改为20HZ
  8. 招聘时最看重应聘者的什么特质?
  9. Error排错:container runtime network not ready
  10. win10系统更新后C盘逐渐变小解决方法
  11. 硬盘被重新分区并格式化后数据恢复教程 (图文并茂)
  12. axios跨域解决方案
  13. 【转】校招优秀简历和普通简历的区别
  14. java的幂等性处理
  15. 磊科路由器如何设置虚拟服务器,nw711磊科路由器设置桥接步骤图文
  16. python助教酱酱是谁_papi酱个人资料
  17. html格式发邮件,怎么用HTML格式发送邮件.既怎么发HTML格式的邮件?
  18. 安全科普:使用Cookie会导致哪些安全问题?
  19. 优维科技加入信通院“AIOps标准工作组”,智能运维之路更进一步
  20. 20176单招计算机专业,对口升学信息技术(计算机)类2017年专业课考试大纲

热门文章

  1. Manage,管道的简单应用,进程池,队列的简单应用
  2. 深入学习JavaScript: apply 方法 详解
  3. 解决vmware“二进制转换和长模式与此平台兼容.....”问题
  4. mini2440 uboot使用nfs方式引导内核,文件系统
  5. Camel In Action 读书笔记 (8)
  6. 【重点 递归构造二叉树】LeetCode 95. Unique Binary Search Trees II
  7. DRAM的动态刷新问题总结
  8. matlab作图显示中文正常,保存图片中文乱码
  9. Qt使用QAudioRecorder进行音频采集,以及声音、热红外和可见光数据采集软件效果
  10. jQuery入门笔记