java中comparable和comparator接口区别分析-亚博电竞手机版

本文要来详细分析一下java中comparable和comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的java开发者继续看下去吧。

comparable 简介

comparable 是排序接口。

若一个类实现了comparable接口,就意味着“该类支持排序”。  即然实现comparable接口的类支持排序,假设现在存在“实现comparable接口的类的对象的list列表(或数组)”,则该list列表(或数组)可以通过 collections.sort(或 arrays.sort)进行排序。

此外,“实现comparable接口的类的对象”可以用作“有序映射(如treemap)”中的键或“有序集合(treeset)”中的元素,而不需要指定比较器。

comparable 定义

comparable 接口仅仅只包括一个函数,它的定义如下:

package java.lang; import java.util.*; public interface comparable {     public int compareto(t o); }

说明:

假设我们通过 x.compareto(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。

comparator 简介

comparator 是比较器接口。

我们若需要控制某个类的次序,而该类本身不支持排序(即没有实现comparable接口);那么,我们可以建立一个“该类的比较器”来进行排序。这个“比较器”只需要实现comparator接口即可。

也就是说,我们可以通过“实现comparator类来新建一个比较器”,然后通过该比较器对类进行排序。

comparator 定义

comparator 接口仅仅只包括两个个函数,它的定义如下:

package java.util; public interface comparator {     int compare(t o1, t o2);     boolean equals(object obj); }

说明:

(01) 若一个类要实现comparator接口:它一定要实现compareto(t o1, t o2) 函数,但可以不实现 equals(object obj) 函数。

为什么可以不实现 equals(object obj) 函数呢? 因为任何类,默认都是已经实现了equals(object obj)的。 java中的一切类都是继承于java.lang.object,在object.java中实现了equals(object obj)函数;所以,其它所有的类也相当于都实现了该函数。

(02) int compare(t o1, t o2) 是“比较o1和o2的大小”。返回“负数”,意味着“o1比o2小”;返回“零”,意味着“o1等于o2”;返回“正数”,意味着“o1大于o2”。

comparator 和 comparable 比较

comparable是排序接口;若一个类实现了comparable接口,就意味着“该类支持排序”。

而comparator是比较器;我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。

我们不难发现:comparable相当于“内部比较器”,而comparator相当于“外部比较器”。

我们通过一个测试程序来对这两个接口进行说明。源码如下:

import java.util.*; import java.lang.comparable; /**  * @desc "comparator"和“comparable”的比较程序。  *   (01) "comparable"  *   它是一个排序接口,只包含一个函数compareto()。  *   一个类实现了comparable接口,就意味着“该类本身支持排序”,它可以直接通过arrays.sort() 或 collections.sort()进行排序。  *   (02) "comparator"  *   它是一个比较器接口,包括两个函数:compare() 和 equals()。  *   一个类实现了comparator接口,那么它就是一个“比较器”。其它的类,可以根据该比较器去排序。  *  *   综上所述:comparable是内部比较器,而comparator是外部比较器。  *   一个类本身实现了comparable比较器,就意味着它本身支持排序;若它本身没实现comparable,也可以通过外部比较器comparator进行排序。  */ public class comparecomparatorandcomparabletest{     public static void main(string[] args) {         // 新建arraylist(动态数组)         arraylist list = new arraylist();         // 添加对象到arraylist中         list.add(new person("ccc", 20));         list.add(new person("aaa", 30));         list.add(new person("bbb", 10));         list.add(new person("ddd", 40));         // 打印list的原始序列         system.out.printf("original  sort, list:%s\n", list);         // 对list进行排序         // 这里会根据“person实现的comparable接口”进行排序,即会根据“name”进行排序         collections.sort(list);         system.out.printf("name      sort, list:%s\n", list);         // 通过“比较器(ascagecomparator)”,对list进行排序         // ascagecomparator的排序方式是:根据“age”的升序排序         collections.sort(list, new ascagecomparator());         system.out.printf("asc(age)  sort, list:%s\n", list);         // 通过“比较器(descagecomparator)”,对list进行排序         // descagecomparator的排序方式是:根据“age”的降序排序         collections.sort(list, new descagecomparator());         system.out.printf("desc(age) sort, list:%s\n", list);         // 判断两个person是否相等         testequals();     }     /**      * @desc 测试两个person比较是否相等。      *   由于person实现了equals()函数:若两person的age、name都相等,则认为这两个person相等。      *   所以,这里的p1和p2相等。      *      *   todo:若去掉person中的equals()函数,则p1不等于p2      */     private static void testequals() {         person p1 = new person("eee", 100);         person p2 = new person("eee", 100);         if (p1.equals(p2)) {             system.out.printf("%s equal %s\n", p1, p2);         } else {             system.out.printf("%s not equal %s\n", p1, p2);         }     }     /**      * @desc person类。      *       person实现了comparable接口,这意味着person本身支持排序      */     private static class person implements comparable{         int age;         string name;         public person(string name, int age) {             this.name = name;             this.age = age;         }         public string getname() {             return name;         }         public int getage() {             return age;         }         public string tostring() {             return name   " - "  age;         }         /**          * 比较两个person是否相等:若它们的name和age都相等,则认为它们相等          */         boolean equals(person person) {             if (this.age == person.age && this.name == person.name)                 return true;             return false;         }         /**          * @desc 实现 “comparable” 的接口,即重写compareto函数。          *  这里是通过“person的名字”进行比较的          */         @override         public int compareto(person person) {             return name.compareto(person.name);             //return this.name - person.name;         }     }     /**      * @desc ascagecomparator比较器      *       它是“person的age的升序比较器”      */     private static class ascagecomparator implements comparator {         @override          public int compare(person p1, person p2) {             return p1.getage() - p2.getage();         }     }     /**      * @desc descagecomparator比较器      *       它是“person的age的升序比较器”      */     private static class descagecomparator implements comparator {         @override          public int compare(person p1, person p2) {             return p2.getage() - p1.getage();         }     } }

下面对这个程序进行说明。

a) person类定义。如下:

private static class person implements comparable{     int age;     string name;         ...     /**       * @desc 实现 “comparable” 的接口,即重写compareto函数。      *  这里是通过“person的名字”进行比较的      */     @override     public int compareto(person person) {         return name.compareto(person.name);         //return this.name - person.name;     }    }

说明:

(01) person类代表一个人,persong类中有两个属性:age(年纪) 和 name“人名”。

(02) person类实现了comparable接口,因此它能被排序。

b) 在main()中,我们创建了person的list数组(list)。如下:

// 新建arraylist(动态数组) arraylist list = new arraylist(); // 添加对象到arraylist中 list.add(new person("ccc", 20)); list.add(new person("aaa", 30)); list.add(new person("bbb", 10)); list.add(new person("ddd", 40));

c) 接着,我们打印出list的全部元素。如下:

// 打印list的原始序列 system.out.printf("original sort, list:%s\n", list);

d) 然后,我们通过collections的sort()函数,对list进行排序。

由于person实现了comparable接口,因此通过sort()排序时,会根据person支持的排序方式,即 compareto(person person) 所定义的规则进行排序。如下:

// 对list进行排序 // 这里会根据“person实现的comparable接口”进行排序,即会根据“name”进行排序 collections.sort(list); system.out.printf("name sort, list:%s\n", list);

e) 对比comparable和comparator

我们定义了两个比较器 ascagecomparator 和 descagecomparator,来分别对person进行 升序 和 降低 排序。

e.1) ascagecomparator比较器

它是将person按照age进行升序排序。代码如下:

/**  * @desc ascagecomparator比较器  *       它是“person的age的升序比较器”  */ private static class ascagecomparator implements comparator {     @override     public int compare(person p1, person p2) {         return p1.getage() - p2.getage();     } }

e.2) descagecomparator比较器

它是将person按照age进行降序排序。代码如下:

/**  * @desc descagecomparator比较器  *       它是“person的age的升序比较器”  */ private static class descagecomparator implements comparator {     @override     public int compare(person p1, person p2) {         return p2.getage() - p1.getage();     } }

f) 运行结果

运行程序,输出如下:

original  sort, list:[ccc - 20, aaa - 30, bbb - 10, ddd - 40] name      sort, list:[aaa - 30, bbb - 10, ccc - 20, ddd - 40] asc(age)  sort, list:[bbb - 10, ccc - 20, aaa - 30, ddd - 40] desc(age) sort, list:[ddd - 40, aaa - 30, ccc - 20, bbb - 10] eee - 100 equal eee - 100
展开全文
内容来源于互联网和用户投稿,文章中一旦含有亚博电竞手机版的联系方式务必识别真假,本站仅做信息展示不承担任何相关责任,如有侵权或涉及法律问题请联系亚博电竞手机版删除

最新文章

网站地图