Java里的optical comparatorr这两个接口的排序该如何去很好的理解able和Compar

9524人阅读
JAVA(19)
1.比较后,返回0,1,-1 的结果,可以用
&& return (thisVal&anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
以下转自 /blog/200987
两种比较接口分析
中有两种比较接口:
Comparable
Comparator
Comparable
是通用的接口,用户可以实现它来完成自己特定的比较,而
Comparator
可以看成一种算法的实现,在需要容器集合实现比较功能的时候,来指定这个比较器,这可以看成一种设计模式,将算法和数据分
前者应该比较固
定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。
一个类实现了
Camparable
接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这
个类对象组成的集合就可以使用
方法排序了。
Comparator
的作用有两个:
、如果类的设计师没有考虑到
的问题而没有实现
Comparable
接口,可以通过
Comparator
来实现比较算法进行排序;
、为了使用不同的排序标准做准备,比如:升序、降序或其他什么序。
2 Comparable
Comparable&T& {
compareTo(T o);
java.lang.
Comparable
接口定义类的自然顺序,实现该接口的类就可以按这种方式排序。
int compareTo(Object o):
比较当前实例对象与对象
,如果位于对象
之前,返回负值,如果两个对象在排序中位置相同,则返回
,如果位于对象
后面,则返回正值。
Java 2 SDK
中有二十四个类实现
Comparable
接口。下表展示了
种基本类型的自然排序。虽然一些类共享同一种自然排序,但只有相互可比的类才能排序。
BigDecimal,BigInteger,Byte,Double,
Float,Integer,Long,Short
按数字大小排序
值的数字大小排序
按字符串中字符
Comparable
接口创建自己的类的排序顺序,只是实现
compareTo()
方法的问题。通常就是依赖几个数据成员的自然排序。同时类也应该覆盖
hashCode()
以确保两个相等的对象返回同一个哈希码。
这个接口的作
用:如果数组或者集合中的(类)元素实现了该接口的话
我们就可以调用
Collections.sort
Arrays.sort
排序,或应用于有序集合
下面设计一个有
Comparable
接口,以年龄为第一关键字,姓名为第二关键字升序排序。
Person.java
implements
Comparable&Person& {
age, String
compareTo(Person person) {
person.getAge();
(cop != 0)
&&&&&&&&&&
&&&&&&&&&&
.compareTo(person.
getAge() {
getName() {
hashCode() {
result = 17;
result = 37 * result +
result = 37 * result +
.hashCode();
equals(Object
instanceof
&&&&&&&&&&
Person person = (Person)
== person.
.equals(person.
toString() {
Arrays.sort
ArraysSortUnit.java
java.util.A
ArraysSortUnit {
main(String[]
Person[] ps = {
Person(20,
Person(20,
&&&&&&&&&&&&&
Person(30,
Person(20,
&&&&&&&&&&&&&
Person(40,
Person(61,
&&&&&&&&&&&&&
Person(20,
.println(Arrays.toString
Arrays.sort
.println(Arrays.toString
[20{Tom}, 20{Jeff}, 30{Mary},
20{Ada}, 40{Walton}, 61{Peter}, 20{Bush}]
[20{Ada}, 20{Bush}, 20{Jeff}, 20{Tom}, 30{Mary},
40{Walton}, 61{Peter}]
Collections.sort
CollctionsSortUnit.java
java.util.A
java.util.C
CollctionsSortUnit {
main(String[]
Person[] ps = {
Person(20,
Person(20,
&&&&&&&&&&&&&
Person(30,
Person(20,
&&&&&&&&&&
Person(40,
Person(61,
&&&&&&&&&&&&&
Person(20,
.println(Arrays.toString
Collections.sort
(Arrays.asList
.println(Arrays.toString
[20{Tom}, 20{Jeff}, 30{Mary},
20{Ada}, 40{Walton}, 61{Peter}, 20{Bush}]
[20{Ada}, 20{Bush}, 20{Jeff}, 20{Tom}, 30{Mary},
40{Walton}, 61{Peter}]
TreeSetUnit.java
java.util.TreeS
TreeSetUnit {
main(String[]
TreeSet&Person& set =
TreeSet&Person&();
Person(20,
Person(20,
Person(30,
Person(20,
Person(40,
Person(61,
Person(20,
.println(set);
[20{Ada}, 20{Bush}, 20{Jeff}, 20{Tom}, 30{Mary},
40{Walton}, 61{Peter}]
TreeMapUnit.java
java.util.TreeM
TreeMapUnit {
main(String[]
TreeMap&Person, String& map =
TreeMap&Person, String&();
Person(20,
Person(20,
Person(30,
Person(20,
Person(40,
Person(61,
Person(20,
.println(map);
{20{Ada}=Ada, 20{Bush}=Bush,
20{Jeff}=Jeff, 20{Tom}=Tom, 30{Mary}=Mary, 40{Walton}=Walton,
61{Peter}=Peter}&
转自 http://www.blogjava.net/fastunit/archive//191533.html
三、Comparator和Comparable的区别
先看一下使用Comparator对User集合实现排序的方式:
&java.util.A
&UserComparator&
implements
&Comparator&{
&compare(Object&o1,&Object&o2)&{
&((User)&o1).getAge()&
&((User)&o2).getAge();
&&&*&测试方法
&main(String[]&args)&{
&&&&User[]&users&
&User[]&{&
&&&&Arrays.sort(users,&
&UserComparator());
&&&&&&User&user&
&users[i];
&&&&&&System.out.println(user.getId()&
&user.getAge());
一个类实现了Camparable接口则表明这个类的对象之间是可以相互比较的,这个类对象组成的集合就可以直接使用sort方法排序。
Comparator可以看成一种算法的实现,将算法和数据分离,Comparator也可以在下面两种环境下使用:
1、类的设计师没有考虑到比较问题而没有实现Comparable,可以通过Comparator来实现排序而不必改变对象本身
2、可以使用多种排序标准,比如升序、降序等
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:111212次
积分:1463
积分:1463
排名:千里之外
原创:40篇
转载:11篇
评论:19条
(1)(2)(1)(1)(7)(1)(7)(6)(8)(1)(1)(9)(6)今天看啥 热点:
Java中Comparator接口,javacomparator接口Comparator位于java.util包下
public interface Comparator&T&
强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
当且仅当对于一组元素 S 中的每个 e1 和 e2 而言,<pare(e1, e2)==0 与 e1.equals(e2) 具有相等的布尔值时,Comparator c 强行对 S 进行的排序才叫做与 equals 一致 的排序。
当使用具有与 equals 不一致的强行排序能力的 Comparator 对有序 set(或有序映射)进行排序时,应该小心谨慎。假定一个带显式 Comparator c 的有序 set(或有序映射)与从 set S 中抽取出来的元素(或键)一起使用。如果 c 强行对 S 进行的排序是与 equals 不一致的,那么有序 set(或有序映射)将是行为&怪异的&。尤其是有序 set(或有序映射)将违背根据 equals 所定义的 set(或映射)的常规协定。
例如,假定使用 Comparator c 将满足 (a.equals(b) && c.compare(a, b) != 0) 的两个元素 a 和 b 添加到一个空 TreeSet 中,则第二个 add 操作将返回 true(树 set 的大小将会增加),因为从树 set 的角度来看,a 和 b 是不相等的,即使这与 Set.add 方法的规范相反。
注:通常来说,让 Comparator 也实现 java.io.Serializable 是一个好主意,因为它们在可序列化的数据结构(像 TreeSet、TreeMap)中可用作排序方法。为了成功地序列化数据结构,Comparator(如果已提供)必须实现 Serializable。
在算术上,定义给定 Comparator c 对给定对象 set S 实施强行排序 的关系式 为:
{(x, y) such pare(x, y) &= 0}.
此整体排序的商 (quotient) 为:
{(x, y) such pare(x, y) == 0}.
它直接遵循 compare 的协定,商是 S 上的等价关系,强行排序是 S 上的整体排序。当我们说 c 强行对 S 的排序是与 equals 一致 的时,意思是说排序的商是对象的 equals(Object) 方法所定义的等价关系:
{(x, y) such that x.equals(y)}.
此接口是 Java Collections Framework 的成员。
从以下版本开始:1.2另请参见:Comparable, Serializable
返回值等于0说明相等,比较的是Unicode顺序,注意如果输入都是数字与数字比较结果可能不同因为&111&就是排在&2&之前
我觉得楼上说的和楼主想问的不是一个概念,楼主是知道怎么new一个已经实现了接口的类的,只是不太明白为什么能够直接new一个接口。 我给你个通俗易懂的解释,其实这一句: Comparator OrderIsdn = new Comparator(){ 相当于(不是标准语法,只是说明原理,帮助理解): Comparator OrderIsdn = new (MyComp implements Comparator)(){ 只是由于是匿名类没有名字,所以就变成你看到的那样了。 实际上,你问的这种写法是java的标准写法,它的意义是我将要实现这个接口并且由这个实现创建一个对象。注意并不是直接实例化接口(虽然看起来像),而是先实现(后面的一对大括号中的代码)再实例化。
相关搜索:
相关阅读:
相关频道:
&&&&&&&&&&&&&&&&
Java编程最近更新1.什么是Comparable接口
此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序 ,类的 compareTo 方法被称为它的自然比较方法 。实现此接口的对象列表(和数组)可以通过 Collections.sort (和 Arrays.sort )进行自动排序。实现此接口的对象可以用作有序映射表中的键或有序集合中的元素,无需指定比较器。 强烈推荐(虽然不是必需的)使自然排序与 equals 一致。所谓与equals一致是指对于类 C 的每一个 e1 和 e2 来说,当且仅当 (e1.compareTo((Object)e2) == 0) 与e1.equals((Object)e2) 具有相同的布尔值时,类 C 的自然排序才叫做与 equals 一致 。
2.实现什么方法
int compareTo(T o)
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
强烈推荐 (x.compareTo(y)==0) == (x.equals(y)) 这种做法,但不是 严格要求这样做。一般来说,任何实现 Comparable 接口和违背此条件的类都应该清楚地指出这一事实。推荐如此阐述:“注意:此类具有与 equals 不一致的自然排序。”
o - 要比较的对象。
负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。
ClassCastException - 如果指定对象的类型不允许它与此对象进行比较。
java.util.*;&#160;&#160;
public class
EmployeeSortTest {&#160;&#160;
&#160;&#160;&#160;&#160; * @param args
&#160;&#160;&#160;&#160; */
public static void
main(String[] args) {&#160;&#160;
// TODO Auto-generated method stub
&#160;&#160;&#160;&#160;&#160;&#160;&#160; Employee[] staff =&#160; new
Employee[ 3 ];&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; staff[ 0 ] =&#160; new
Employee( &harry Hacker& , 35000 );&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; staff[ 1 ] =&#160; new
Employee( &carl cracke& , 75000 );&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; staff[ 2 ] =&#160; new
Employee( &tony Tester& , 38000 );&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; Arrays.sort(staff); //sort方法可以实现对对象数组排序,但是必须实现 Comparable接口
/*Comparable接口原型为:
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; * public interface Comparable&T&
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; * {
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; *&#160;&#160;&#160;&#160;&#160; int compareTo(T other);//接口的中方法自动属于public方法
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; * }
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; */
for (Employee e: staff)&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println( &id=& +e.getId()+ &&#160; name=& +e.getName()+&#160;&#160;
&.salary=& +e.getSalary());&#160;&#160;
&#160;&#160;&#160; }&#160;&#160;
}&#160;&#160;
* 因为要实现对Employee对象的排序,所以在Employee类中要实现Comparable接口,
* 也就是要实现comepareTo()方法
Employee&#160; implements
Comparable&Employee&&#160;&#160;
{&#160;&#160;
Employee(String n, double
s)&#160;&#160;
&#160;&#160;&#160; {&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; name =&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; salary =&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; Random ID =&#160; new
Random();&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; id = ID.nextInt(
);&#160;&#160;
&#160;&#160;&#160; }&#160;&#160;
public int
getId()&#160;&#160;
&#160;&#160;&#160; {&#160;&#160;
return &#160;&#160;
&#160;&#160;&#160; }&#160;&#160;
String getName()&#160;&#160;
&#160;&#160;&#160; {&#160;&#160;
return &#160;&#160;
&#160;&#160;&#160; }&#160;&#160;
public double
getSalary()&#160;&#160;
&#160;&#160;&#160; {&#160;&#160;
return &#160;&#160;
&#160;&#160;&#160; }&#160;&#160;
public void
raiseSalary( double
byPercent)&#160;&#160;
&#160;&#160;&#160; {&#160;&#160;
raise&#160; = salary *byPercent/ 100 ;&#160;&#160;
&#160;&#160;&#160;&#160;&#160;&#160;&#160; salary+=&#160;&#160;
&#160;&#160;&#160; }&#160;&#160;
public int
compareTo(Employee other)&#160;&#160;
&#160;&#160;&#160; {&#160;&#160;
if (id&other.id) //这里比较的是什么 sort方法实现的就是按照此比较的东西从小到大排列
- 1 ;&#160;&#160;
if (id&other.id)&#160;&#160;
return 1 ;&#160;&#160;
return 0 ;&#160;&#160;
&#160;&#160;&#160; }&#160;&#160;
private int &#160;&#160;
S&#160;&#160;
private double &#160;&#160;
4.与Comparator的区别
Comparator位于包java.util下,而Comparable位于包java.lang下,Comparable接口将比较代码嵌入自身类中,而后者在一个独立的类中实现比较。 如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过&#160; Comparator来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:升序、降序。
我们看一个Comparator的例子:
import java.util.TreeS
class NumComparator implements Comparator&NameTag& {
&#160;&#160;&#160; public int compare (NameTag left,NameTag right) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160; return(left.getNumber() - right.getNumber());
&#160;&#160;&#160; }
public class CollectionNine {
&#160;&#160;&#160; public static void main(String arg[]) {
&#160;&#160;&#160;&#160;&#160;&#160;&#160; new CollectionNine();
&#160;&#160;&#160; }
&#160;&#160;&#160; CollectionNine() {
&#160;&#160;&#160;&#160;&#160;&#160;&#160; NumComparator comparator = new NumComparator();
&#160;&#160;&#160;&#160;&#160;&#160;&#160; TreeSet&NameTag& set = new TreeSet&NameTag&(comparator);
&#160;&#160;&#160;&#160;&#160;&#160;&#160; set.add(new NameTag(&Agamemnon&,300));
&#160;&#160;&#160;&#160;&#160;&#160;&#160; set.add(new NameTag(&Cato&,400));
&#160;&#160;&#160;&#160;&#160;&#160;&#160; set.add(new NameTag(&Plato&,100));
&#160;&#160;&#160;&#160;&#160;&#160;&#160; set.add(new NameTag(&Zeno&,200));
&#160;&#160;&#160;&#160;&#160;&#160;&#160; set.add(new NameTag(&Archimedes&,500));
&#160;&#160;&#160;&#160;&#160;&#160;&#160; for(NameTag tag : set)
&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; System.out.println(tag);
&#160;&#160;&#160; }
阅读(...) 评论()实体类:parable(接口) + comareTo(重写方法),业务排序类 parator(接口) + compare(重写方法).这两个接口我们非常的熟悉,但是 在用的时候会有一些不知道怎么下手的感觉,现在用案例进行总结,消除对这个知识点的理解盲区(个人的理解,如果有错误 请多多指教)。一,在实际的需求中,我们需要根据对象的各种属性(标题,时间,点击率,销售额...)进行排序(升序,降序),可以在数据库的sql上进行处理,但是 不是每一个场景 都适合在sql上进行处理,我们有时候需要在程序根据不同的属性,对一个对象进行各种排序 通过页面呈现给用户。下面有这样的一个需求,一种商品(商品名,销售量,生产日期),根据生产日期降序 销售量升序 商品名称降序思路:首先按照日期降序,如果日期相同 按照销售量升序,如果销售量相同,按周商品的名称降序1,创建需要比较的对象的java bean创建 Bean的快捷键:1),带参数的构造器:// Shift + Alt + S --&O2),不带参数的构造器: //Alt + / 生成空的构造方法3),生成 get set方法:// Shift + Alt + S --& R + Table + Enter + Shift +Table --&Enter/** * 商品po类 */public class Items implements parable&Items& {private Sprivate Date pubTpublic Items() {}public Items(String title, int hits, Date pubTime) {super();this.title =this.hits =this.pubTime = pubT}public String getTitle() {}public void setTitle(String title) {this.title =}public int getHits() {}public void setHits(int hits) {this.hits =}public Date getPubTime() {return pubT}public void setPubTime(Date pubTime) {this.pubTime = pubT}//时间降序 点击量升序 标题降序@Overridepublic int compareTo(Items o) {int result = 0;//按照生产时间降序result = - pareTo(o.pubTime);if(0==result){//如果生产时间相同 就按照销售量升序排列result = this.hits-o.if(0==result){//如果销售量相同 按照名字降序排列result = - pareTo(o.title);}}}@Overridepublic String toString() {StringBuilder sb = new StringBuilder();sb.append("商品名称").append(this.title);sb.append("销售量").append(this.hits);sb.append("生产时间").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime)).append("/n");return sb.toString();}}2,造数据,比较//时间降序, 销售量升序, 标题降序public static void main(String[] args) {List&Items& item = new ArrayList&Items&();item.add(new Items("abcitems",30,new Date(System.currentTimeMillis()-)));item.add(new Items("abcfgitems" ,30,new Date(System.currentTimeMillis()-)));item.add(new Items("abcditems" ,100,new Date()));item.add(new Items("abefNews",50,new Date(System.currentTimeMillis()-)));System.out.println("----------排序前----------");System.out.println(item);System.out.println("----------排序后----------");Collections.sort(item);System.out.println(item);}二,Comparator的应用场景一般比较字符串是按照unicode的大小进行排序的,但是我需要按照字符串的长度进行排序,下面是实现的案例:首先,定义比较的业务规则/** * 定义业务的比较规则,我需要按照字符串的长度进行比较(在实际的场景中,可以根据业务的需求,灵活的改变比较规则,实现排序) */public class CompareString implements parator&String& {@Overridepublic int compare(String o1, String o2) {int len1 = o1.length();int len2 = o2.length();return -(len1-len2);//需要按照降序排列}}比较 字符串的长度,按照 降序排列public static void main(String[] args) {List&String&list = new ArrayList&String&(); list.add("abc"); list.add("abcd"); list.add("ab"); list.add("abd"); Collections.sort(list,new CompareString()); System.out.println(list); //[abcd, abc, abd, ab]}比如 商品,我需要按照价格的降序排列,代码如下:商品 po类/** * 商品po类 */public class Products {private Spublic Products() {}public Products(String title, int price) {super();this.title =this.price =}public String getTitle() {}public void setTitle(String title) {this.title =}public int getPrice() {}public void setPrice(int price) {this.price =}@Overridepublic String toString() {return "title=" + title+",price=" + price+"/n";}}定义比较规则:/** * 按照价格的降序排列 */ public class ProductCompare implements parator&Products& {@Override public int compare(Products o1, Products o2) { return -( o1.getPrice()-o2.getPrice()&0?1: (o1.getPrice()==o2.getPrice()?0:-1));}}数据比较:public static void main(String[] args) {List&Products& product
= new ArrayList&Products&();product.add(new Products("a",120));product.add(new Products("b",143432));product.add(new Products("c",1892));product.add(new Products("d",11092));Collections.sort(product,new ProductCompare());System.out.println(product);结果: [title=b,price=143432title=d,price=11092 title=c,price=1892 title=a,price=120 ]}
最新教程周点击榜
微信扫一扫

我要回帖

更多关于 optical comparator 的文章

 

随机推荐