对象排序之Comparator,Comparable接口区别(华为面试题)

现有一个类person有三个属性,分别是name,age,sex。有一个List对象,保存了很多person对象的实例,请编写一个函数,对List里的实例进行排序。条件:18岁以上的人,排序顺序:性别,年龄,姓名全部降序。

给了个类,要求编写一段代码,给以下类型的数据排序(按index降序排): 
public class A{ 
  public int index ;  
  public String str; 
  public …… ; 

条件: 
1.数据量很大,要求性能够; 
2.扩展性好:按其他数据类型(如 String str,……)排序的时候,不需要修改组件,以后还可能增加其他类型的数据。 
(提示:可以调用现成的java.util包中的排序.) 

对象排序之Comparator,Comparable接口区别: 

1.comparable是通用的接口,用户可以实现它来完成自己特定的比较,而comparator可以看成一种算法的实现,在需要容器集合 collection需要比较功能的时候,来指定这个比较器,这可以看出一种设计模式(策略模式Strategy),将算法和数据分离,就像C++ STL中的函数对象一样。 
2.前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用。可以说前者属于“静态绑定”,而后者可以“动态绑定”。 
3.一个类实现了Camparable接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用Sort方法排序了。 
4.而Comparator的作用有两个: 
 a,如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过Comparator来实现比较算法进行排序 
 b,可以更加灵活实现排序规则,为了使用不同的排序标准做准备,比如:升序、降序,或者将来想通过类的其他字段进行排序 

Name类,实现comparable接口来对对象进行排序: 

  1. public class Name implements Comparable<Name>{  
  2.  public String firstName, lastName, id;  
  3.     
  4.  public Name(String firstName,String lastName,String id){  
  5.           this.firstName=firstName;  
  6.           this.lastName=lastName;  
  7.           this.id=id;  
  8.       }  
  9.      public int compareTo(Name o) {          //重写  
  10.           int lastCmp=lastName.compareTo(o.lastName);  
  11.           return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));  
  12.       }     
  13.      public String toString(){                //便于输出测试  
  14.           return firstName+" "+lastName;  
  15.       }  
  16. }  

NameSort类,测试  
  1. import java.util.*;  
  2. public class NameSort {  
  3.  public static void main(String[] args) {  
  4.   // TODO Auto-generated method stub  
  5.    Name[] nameArray = new Name[]{  
  6.                 new Name("John""Lennon","3556465464644343"),  
  7.                 new Name("Karl""Marx","3556465461111111"),  
  8.                 new Name("Groucho""Marx","3805236412578"),  
  9.                 new Name("Oscar""Grouch","8854321622238")  
  10.             };  
  11.             Arrays.sort(nameArray);  
  12.             for(int i=0;i<nameArray.length;i++){  
  13.                 System.out.println(nameArray[i].toString());  
  14.             }  
  15.  }  
  16. }  

更加灵活的是方式是实现Comparator接口,使用Collections.sort(List<T> list, Comparator<? super T> c)这个方法进行排序:  
FIRST_NAME_ORDER类 
  1. import java.util.*;  
  2. public class FIRST_NAME_ORDER implements Comparator<Name>{  
  3.  public int compare(Name n1, Name n2) {  
  4.         int firstCmp=n1.firstName.compareTo(n2.firstName);  
  5.         return (firstCmp!=0?firstCmp:n1.lastName.compareTo  
  6.                 (n2.firstName));  
  7.  }  
  8. }  
在上面的NameSort中将 Arrays.sort(nameArray);替换成下面语句 
  1. List<Name> list=Arrays.asList(nameArray); //将名字数组转化为List  
  2. Collections.sort(list,new FIRST_NAME_ORDER());  
总结: 
1.这里自定义FIRST_NAME_ORDER,通过Collections.sort(List,Comparator)实现排序,当需求有变需要按照其他规则(比如id)排序时,只有重新定义一个Comaprator----ID_ORDER_Comparator,而不用修改Name或原来的排序器FIRST_NAME_ORDER,然后修改客户端代码,只有就基本满足了程序设计的一个重要原则---开闭原则,即可以通过增加新类方便的扩充新功能,满足新需求而不用修改原来的代码。 
2.如果我们采用让Name实现Comaparable接口,则在想采用新的排序规则时,必须修改Name里的 comareTo(Object o)方法,这样就违反了开闭原则,所以应该用Comparator,而不是Comparable.
 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值