`

(转)comparator和comparable接口

 
阅读更多
http://fuxueliang.com/tech/2013/05/26/java-sorting-comparator-vs-comparable-tutorial/

Comparable
一个实现了comparable接口的对象的实例可以被用于和相同对象的不同实例做对比。它本身必须实现java.lang.Comparable的接口,这样它就拥有了对比的能力。

Comparator
一个实现了comparator接口的对象能够对比不同的对象。它不能用于同一个类的不同实例的对比,但是可以用于其他的类的实例做对比。它必须实现java.util.Comparator的接口。

我们需要对比对象么?
最简单的答案就是需要对比。当有一个对象的列表的时候,在有些情况下你必须把这些对象按照不同的排序规则来排序。举例来说:考虑一个web页面需要显示职工的列表。通常情况下职工列表是按照职工的ID来排序。同样也可以根据姓名或者年龄来排序。在这些情况下有了这两个概念就会非常便于实现这个功能。

如何使用
在Java中有两个接口来实现Comparable和Comparator,每一个对象都有一个必须实现的接口。分别是:

java.lang.Comparable: int compareTo(Object o1)

这个方法用于当前对象与o1对象做对比,返回int值,分别的意思是:

positive – 当前对象大于o1
zero – 当前对象等于o1
negative – 当前对象小于o1
java.util.Comparator: int compare(Object o1, Objecto2)

这个方法用于o1与o2对象做对比,返回int值,分别的意思是:

positive – o1大于o2
zero – o1等于o2
negative – o1小于o2
java.util.Collections.sort(List) 和 java.util.Arrays.sort(Object[]) 方法被用来排列使用内在排序(natural ordering)方式的对象。(译者注:可参见java.util.List#sort() )

java.util.Collections.sort(List, Comparator) 和 java.util.Arrays.sort(Object[], Comparator)方法在Comparator如果可供比较的时候会被用到。

Employee的例子可以非常好的来解释这两个概念。首先我们写一个简单的Java bean来代表Employee。

public class Employee {
private int empId;
private String name;
private int age;

public Employee(int empId, String name, int age) {
// set values on attributes
}
// getters & setters
}
下面我们将使用一个工具类来构造一个Employees List,我们会对这个List处理不同的排序需求来演示。在下面的代码中Employees比较随意的被add到一个List中。

import java.util.*;

public class Util {

public static List<Employee> getEmployees() {

List<Employee> col = new ArrayList<Employee>();

col.add(new Employee(5, "Frank", 28));
col.add(new Employee(1, "Jorge", 19));
col.add(new Employee(6, "Bill", 34));
col.add(new Employee(3, "Michel", 10));
col.add(new Employee(7, "Simpson",);
col.add(new Employee(4, "Clerk",16 ));
col.add(new Employee(8, "Lee", 40));
col.add(new Employee(2, "Mark", 30));

return col;
}
}
内在顺序(natural ordering)排序
职员的内在排序将根据Employee的id来排序。所以上面的Employee的类必须有可以对比的能力,如下面代码所示:

public class Employee implements Comparable<Employee> {
private int empId;
private String name;
private int age;

/**
* Compare a given Employee with this object.
* If employee id of this object is
* greater than the received object,
* then this object is greater than the other.
*/
public int compareTo(Employee o) {
return this.empId - o.empId ;
}
….
}
添加的compareTo()的方法为这个类的实例替换了默认的内在排序。所以如果是一个Employee对象的集合使用Collections.sort(List)来排序;排序会根据compareTo()方法里面定义的规则来完成。

我们接下来再写一个类来测试这个内在排序的机制。这个类使用Collections.sort(List)方法来对给定的List按照内在顺序来完成排序。

import java.util.*;

public class TestEmployeeSort {

public static void main(String[] args) {    
List coll = Util.getEmployees();
Collections.sort(coll); // sort method
printList(coll);
}

private static void printList(List<Employee> list) {
System.out.println("EmpId\tName\tAge");
for (Employee e: list) {
System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
}
}
}
执行下上面的代码,检查下输出结果。如下面所示:

EmpId Name Age
1 Jorge 19
2 Mark 30
3 Michel 10
4 Clerk 16
5 Frank 28
6 Bill 34
7 Simp 8
8 Lee 40
我们通过输出可以看到的是,这个列表是根据employee的id来完成的排序。因为employee的id是个int值,所以这些employee的实例就按照id从小到大的顺序完成了排序。

根据其他字段排序
如果你需要根据employee的其他字段来进行排序,我们需要修改Employee的类的compareTo()方法。但是我们也会因此而失去基于Employee的ID的排序机制。如果我们在不同的场合需要有不同的字段来进行排序的话,这样使用可能不是一个好的选择。但是不要担心;Comparator可以帮助我们。

接下来我们写一个类实现java.util.Comparator的接口,你可以对Employees使用你希望使用的任何字段进行排序,而不需要对Employee的类本身进行任何改动。Employee的类不需要实现java.lang.Comparable或者java.util.Comparator接口。

根据name字段排序
下面的EmpSortByName是根据name的字段来对Employee的实例做排序的类。在这个类中,compare()方法实现了这个排序机制。在compare()方法中,我们可以得到两个Employee的实例,并通过返回值我们可以知道哪个对象比较大。

public class EmpSortByName implements Comparator<Employee>{

public int compare(Employee o1, Employee o2) {
return o1.getName().compareTo(o2.getName());
}
}
注意这里的使用的是String类的compareTo()方法比较name字段(字段也是字符串)。

我们现在可以测试下这个排序的机制,你必须使用Collections.sort(List, Comparator)这个方法,而不是使用Collections.sort(List)方法。现在根据下面的代码来改造下TestEmployeeSort这个类,我们可以看下EmpSortByName comparator的方式的内部的排序方法是怎样的。

import java.util.*;

public class TestEmployeeSort {

public static void main(String[] args) {

List coll = Util.getEmployees();
//Collections.sort(coll);
//use Comparator implementation
Collections.sort(coll, new EmpSortByName());
printList(coll);
}

private static void printList(List<Employee> list) {
System.out.println("EmpId\tName\tAge");
for (Employee e: list) {
System.out.println(e.getEmpId() + "\t" + e.getName() + "\t" + e.getAge());
}
}

}
结果如下面所示:

EmpId Name Age
6 Bill 34
4 Clerk 16
5 Frank 28
1 Jorge 19
8 Lee 40
2 Mark 30
3 Michel 10
7 Simp 8
检查Employees的排序是否已经按照name字段进行了正确的排序。你看到输出的结果应该是按照字母排好序的。

Sorting by empId field
甚至是先前我们使用Comparable实现的按照Employee ID实现的排序功能一样可以使用Comparator来实现,如下面代码所示:

public class EmpSortByEmpId implements Comparator<Employee>{

public int compare(Employee o1, Employee o2) {
return o1.getEmpId() - o2.getEmpId();
}
}

//补充:比如有的时候先按职位排序,职位相同的再按工号排序:

   public int compareTo(Employee e)
  return new compareToBuilder().append(position,o.position)
                                .append(id,o.id).toComparison);
}
分享到:
评论

相关推荐

    comparator接口与Comparable接口的区别

    Comparator接口与Comparable接口是Java语言中两个重要的接口,它们都是用于比较和排序自定义类的对象的大小的。虽然它们两个都是用于比较的接口,但是它们有着不同的实现方式和应用场景。 相同之处:Comparator接口...

    Comparable接口和Comparator使用示例

    Comparable 接口和 Comparator 使用示例 在 Java 编程语言中,比较和排序是非常常见的操作。Comparable 接口和 Comparator 是两种常用的比较和排序方式。在本文中,我们将通过实例代码,详细介绍 Comparable 接口和...

    java的Comparator和Comparable.docx

    在 Java 中,Comparator 和 Comparable 是两个非常重要的接口,它们用于对象的排序操作。这两个接口都是在 java.util 包中定义的,主要用于定制排序规则。 **一、Comparator 接口** Comparator 接口允许我们创建...

    java排序Comparator和Comparable

    在Java编程语言中,排序是数据处理中一个非常常见的需求,而`Comparator`和`Comparable`接口则是实现排序的关键工具。这两个接口都是用于比较对象,但它们的应用场景和使用方式有所不同。 首先,`Comparable`接口是...

    java中Comparable和Comparator的区别

    此外,Comparable接口的实现通常会影响类的 equals() 和 hashCode() 方法,因为它们之间的关系是:如果两个对象相等(根据 equals()),那么它们的 compareTo() 方法应该返回 0。而Comparator接口则不会影响对象的 ...

    Comparable&Comparator区别

    #### 二、Comparable接口解析 ##### 1. 概念介绍 `Comparable`接口位于`java.lang`包中,它定义了一个单一的方法`compareTo`。这个接口适用于那些具有自然顺序的对象。当一个类实现了`Comparable`接口时,意味着它...

    浅析Java中comparator接口与Comparable接口的区别

    首先,Comparable接口是一个排序接口,它定义了一个单一的方法`compareTo(T o)`,使得实现了Comparable接口的类的对象能够进行自然排序。这意味着如果你有一个实现了Comparable接口的对象列表(如List),你可以直接...

    Java中Comparable和Comparator的区别

    例如,当我们有一个自定义类的集合,并且需要按照多种方式进行排序时,可以先让类实现Comparable接口,表示其默认的排序规则,然后在需要其他排序规则时,创建Comparator实例并传递给Collections.sort()或者TreeSet...

    详解Java中Comparable和Comparator接口的区别

    * 一个类实现了Comparable接口,就意味着“该类本身支持排序”,它可以直接通过Arrays.sort() 或 Collections.sort()进行排序。 * (02) "Comparator" * 它是一个比较器接口,包括两个函数:compare() 和 equals...

    对比Java中的Comparable排序接口和Comparator比较器接口

    例如,Java中的String、Integer等内置类都实现了Comparable接口,可以方便地进行比较和排序。当你有一个实现了Comparable接口的对象列表或数组时,可以直接使用Collections.sort()或Arrays.sort()对其进行排序。...

    Java中Comparator接口与Comparable接口的区别

    1. Comparator 和 Comparable 相同的地方  他们都是java的一个接口, 并且是用来对自定义的class比较大小的,  什么是自定义class: 如 public class Person{ String name; int age }.  当我们有这么一个...

    Comparable和Comparator区分1

    Comparable接口是Java中用于对象排序的关键接口,主要应用于需要自动排序的场景。当一个类实现了Comparable接口,意味着该类的对象具备内在的比较逻辑,可以直接进行比较。例如,我们可以创建一个Person类,让它实现...

    Comparable与Comparator的区别

    **Comparable接口** Comparable接口位于`java.lang`包下,它是一个对象自比较的接口。任何类如果需要进行排序,可以实现Comparable接口。例如,String、Integer等内置类已经实现了Comparable接口,可以方便地进行...

    Comparable接口和Comparator接口的比较

    Comparable接口和Comparator接口是Java中用于排序的关键组件,它们在数据结构如数组、集合和映射的排序过程中扮演着重要角色。接下来我们将深入探讨这两个接口的特性、用途以及它们之间的区别。 1. Comparable接口...

    Comparable与Comparator的区别Java开

    在Java编程语言中,`Comparable`接口和`Comparator`接口是两种重要的排序机制,它们用于对集合中的对象进行比较和排序。理解它们的区别对于任何Java开发者来说都是至关重要的。 首先,`Comparable`接口位于`java....

    Java中Comparable和Comparator 2种实现方式学习

    在Java编程语言中,排序是常见的操作,而`Comparable`和`Comparator`接口则是实现对象排序的两种主要方式。这篇文章将深入探讨这两种实现方式及其在实际编程中的应用。 首先,`Comparable`接口位于`java.lang`包下...

    java 中Comparable与Comparator详解与比较

    Comparable接口定义在`java.lang`包中,它只有一个方法`compareTo(T o)`,用于比较当前对象与另一个对象的大小。当一个类实现了Comparable接口,意味着类的实例可以被自然排序,无需额外的比较器。例如,String类就...

    Java Comparable和Comparator对比详解

    Java Comparable和Comparator对比...在实际项目开发过程中,我们经常需要对某个对象或者某个集合中的元素进行排序,使用 Comparable 接口和 Comparator 接口可以实现自定义的排序规则,提高代码的灵活性和可维护性。

Global site tag (gtag.js) - Google Analytics