java api 接口篇(二)下

http://tech.ddvip.com   2006年11月23日    社区交流

本文详细介绍java api 接口篇(二)下

  在上一节中的有关 Comparable 的许多内容也适用Comparator。编写一个 compare 方法几乎等同于编写一个compareTo 方法,除前者是把两个参数都当作参数之外。compare 方法必须象Comparable 的 compareTo 方法一样,服从同样的四个"技术限制"。出于同样的原因, Comparator 必须对它所比较的对象诱发一个 partial order(部分顺序)。
  假设你有一个称作 EmployeeRecord 的类:
public class EmployeeRecord implements Comparable {
public Name name();
public int employeeNumber();
public Date hireDate();
...
}
 
 
  我们假设 EmployeeRecord 对象的自然排序是对雇员姓名的排序 (就象上一个例子中所定义的)。不幸的是,老板要求我们提出一个按雇员资历排序的列表。这就意味着我们必须做些额外的工作,但是不多。以下是一个将生成所需列表的程序:  
 
import java.util.*; 
 
class EmpSort {
static final Comparator SENIORITY_ORDER = new Comparator() {
public int compare(Object o1, Object o2) {
EmployeeRecord r1 = (EmployeeRecord) o1;
EmployeeRecord r2 = (EmployeeRecord) o2;
return r2.hireDate().compareTo(r1.hireDate());
}
}; 
 
static final Collection employees = ... ; // Employee Database 
 
public static void main(String args[]) {
List emp = new ArrayList(employees);
Collections.sort(emp, SENIORITY_ORDER);
System.out.println(emp);
}
}
 
 
  以上程序中的 Comparator 相当简单。它将它的参数转换为EmployeeRecord, 并依赖适用于 hireDate()方法的 Date 的自然排序。请注意:Comparator 将它的第二个参数的雇用-日期传递给第一个参数,而不是按反方向传递。 这是因为,最新雇用的雇员资历最浅:按照雇用-日期排序将使列表成为反向资历-顺序。另一个获得相同结果的方法是:保持参数顺序,但对比较结果求反。  
 
return -r1.hireDate().compareTo(r2.hireDate());  
 
  两种方法同样可取。使用哪一种,全由你自己。  
 
  以上程序中的 Comparator ,在对 List 进行排序时,效果很好。但有一个小的缺陷:它不能被用来对一个排序的 对象集 (如TreeSetM) 进行排序,因为它生成一个严格的部分(strictly partial) 排序。这意味着这个comparator 使不相等的对象相等。特别的,它会使任意两个雇用日期相同的雇员成为相等。当你为一个 List 排序时,这没关系,但当你使用 Comparator 为一个sort排序的对象集 排序时, 这就是致命的了。如果你将多个雇用日期相同的雇员用Comparator插入到一个TreeSet之中,那么只有第一个将被添加到 set,第二个将被作为一个复制元素而忽略。

责编:豆豆技术应用

正在加载评论...