你好,欢迎来到电脑编程技巧与维护杂志社! 杂志社简介广告服务读者反馈编程社区  
合订本订阅
 
 
您的位置:技术专栏 / Java专栏
如何使用 Comparable ,Comparator 接口
 

在用 java 编程时,经常会有这样的需求:把 list 中的某一类的对象,按照某个对象属性对所有对象在内存中进行排序,那么我们改如何实现呢? 答案是,实现  java 提供的 Comparable 接口。

我们模拟一个需求:按员工的工资从小到大排序员工对象。

我们首先定义个 Employee 类,有个3个实例属性: 员工 id(empId),名称(eName),薪资(sal), 此类实现了 Comparable 接口。


[java]
public class Employee implements Comparable { 
 
    int empId; 
    String eName; 
    double sal; 
    static int i; 
 
    public Employee() { 
        empId = i++; 
        eName = "don't know"; 
        sal = 0.0; 
    } 
 
    public Employee(String eName, double sal) { 
        this.empId = i++; 
        this.eName = eName; 
        this.sal = sal; 
    } 
 
    @Override 
    public String toString() { 
        return "empId " + empId + "\n" + "eName " + eName + "\n" + "sal " + sal; 
    } 
 
    @Override 
    public int compareTo(Object o) { 
        if (this.sal == ((Employee) o).sal) return 0; 
        else if (this.sal > ((Employee) o).sal) return 1; 
        else return -1; 
    } 

public class Employee implements Comparable {

    int empId;
    String eName;
    double sal;
    static int i;

    public Employee() {
        empId = i++;
        eName = "don't know";
        sal = 0.0;
    }

    public Employee(String eName, double sal) {
        this.empId = i++;
        this.eName = eName;
        this.sal = sal;
    }

    @Override
    public String toString() {
        return "empId " + empId + "\n" + "eName " + eName + "\n" + "sal " + sal;
    }

    @Override
    public int compareTo(Object o) {
        if (this.sal == ((Employee) o).sal) return 0;
        else if (this.sal > ((Employee) o).sal) return 1;
        else return -1;
    }
}

我在定义个 ComparableDemo 类


[java]
public class ComparableDemo { 
 
    public static void main(String[] args) { 
        List list = new ArrayList(); 
        list.add(new Employee("Tom",40000.00)); 
        list.add(new Employee("Harry",20000.00)); 
        list.add(new Employee("Maggle",50000.00)); 
        list.add(new Employee("Chris",70000.00)); 
        Collections.sort(list); 
        Iterator iterator = list.iterator(); 
        while(iterator.hasNext()){ 
            Object element = iterator.next(); 
            System.out.println(element.toString()+"\n"); 
        } 
    } 

public class ComparableDemo {

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new Employee("Tom",40000.00));
        list.add(new Employee("Harry",20000.00));
        list.add(new Employee("Maggle",50000.00));
        list.add(new Employee("Chris",70000.00));
        Collections.sort(list);
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            Object element = iterator.next();
            System.out.println(element.toString()+"\n");
        }
    }
}
执行 ComparableDemo main 方法输出如下:

empId 1
eName Harry
sal 20000.0

empId 0
eName Tom
sal 40000.0

empId 2
eName Maggle
sal 50000.0

empId 3
eName Chris
sal 70000.0


实现注意点:


类 Employee 实现了 Comparable 接口,代表此类的对象是可排序的
类 Employee 实现了 Comparable 接口里的 compareTo 方法,此方法里实现的排序的逻辑
类 ComparableDemo 调用  Collections.sort(list); 对 list 的 Employee 的对象按照排序逻辑进行排序
既然有了 Comparable 接口,为什么还需要 Comparator 接口呢?
在这,我提出一个假设:如果我们的 Employee 类按照不同的实例属性排序呢?上面的例子是按照薪资从小到大排序,如果需求变化了,Employee 除了支持按 薪资(sal) 排序,还要支持按照名称(eName) 排序。现在就需要 Comparator 接口来实现了。


我们新建 NameComparator 类,实现 java.util.Comparator 接口,如下:


[java]
public class NameComparator implements Comparator { 
 
    @Override 
    public int compare(Object o1, Object o2) { 
        Employee e1 = (Employee)o1; 
        Employee e2 = (Employee)o2; 
        return e1.eName.compareTo(e2.eName); 
    } 

public class NameComparator implements Comparator {

    @Override
    public int compare(Object o1, Object o2) {
        Employee e1 = (Employee)o1;
        Employee e2 = (Employee)o2;
        return e1.eName.compareTo(e2.eName);
    }
}
我们修改 ComparableDemo 类的代码如下:


[java]
public class ComparableDemo { 
 
    public static void main(String[] args) { 
        List list = new ArrayList(); 
        list.add(new Employee("Tom", 40000.00)); 
        list.add(new Employee("Harry", 20000.00)); 
        list.add(new Employee("Maggle", 50000.00)); 
        list.add(new Employee("Chris", 70000.00)); 
        <SPAN style="COLOR: #ff0000">//Collections.sort(list);  
        Collections.sort(list, new NameComparator());</SPAN> 
        Iterator iterator = list.iterator(); 
        while (iterator.hasNext()) { 
            Object element = iterator.next(); 
            System.out.println(element.toString() + "\n"); 
        } 
    } 

public class ComparableDemo {

    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(new Employee("Tom", 40000.00));
        list.add(new Employee("Harry", 20000.00));
        list.add(new Employee("Maggle", 50000.00));
        list.add(new Employee("Chris", 70000.00));
        //Collections.sort(list);
        Collections.sort(list, new NameComparator());
        Iterator iterator = list.iterator();
        while (iterator.hasNext()) {
            Object element = iterator.next();
            System.out.println(element.toString() + "\n");
        }
    }
}运行 ComparableDemo ,结果如下:


empId 3
eName Chris
sal 70000.0

empId 1
eName Harry
sal 20000.0

empId 2
eName Maggle
sal 50000.0

empId 0
eName Tom
sal 40000.0


  推荐精品文章

·2024年12月目录 
·2024年11月目录 
·2024年10月目录 
·2024年9月目录 
·2024年8月目录 
·2024年7月目录 
·2024年6月目录 
·2024年5月目录 
·2024年4月目录 
·2024年3月目录 
·2024年2月目录 
·2024年1月目录
·2023年12月目录
·2023年11月目录

  联系方式
TEL:010-82561037
Fax: 010-82561614
QQ: 100164630
Mail:gaojian@comprg.com.cn

  友情链接
 
Copyright 2001-2010, www.comprg.com.cn, All Rights Reserved
京ICP备14022230号-1,电话/传真:010-82561037 82561614 ,Mail:gaojian@comprg.com.cn
地址:北京市海淀区远大路20号宝蓝大厦E座704,邮编:100089