黑马程序员技术交流社区

标题: compare compareTo [打印本页]

作者: 24岁???    时间: 2014-6-30 11:05
标题: compare compareTo
compare和compareTo的区别有哪些呢,我看混了
作者: 燿陚√揚葳    时间: 2014-6-30 12:29
Comparable:让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法

如下面的代码:学生对象是不具备比较性的所以让他实现Comparable接口具备比较性

  1. <P>package doo;
  2. /*
  3. * |--TreeSet:可以对Set集合中的元素进行排序
  4. *
  5. * 需求:往集TreeSet合中存储自定义对象学生
  6. * 想按照学生的年龄进行排序
  7. *
  8. * 记住:排序时当主要条件相同时,一定要判断一下次要条件
  9. */
  10. import java.util.*;
  11. class Student implements Comparable{//强制让元素具备比较性
  12. private String name;
  13. private int age;
  14. Student(String name,int age){
  15. this.name=name;
  16. this.age=age;
  17. }
  18. //复写这个接口中的方法,并且让他具备想要的比较性</P>
  19. <P>public int compareTo(Object obj){
  20. if(!(obj instanceof Student))
  21. throw new RuntimeException("不是学生对象!");
  22. Student s=(Student)obj;
  23. System.out.println(this.name+"**Comparable**"+s.name);
  24. if(this.age>s.age)
  25. return 1;
  26. if(this.age==s.age){
  27. return this.name.compareTo(s.name);
  28. }


  29. return -1;
  30. }
  31. public String getName(){
  32. return name;
  33. }
  34. public int getAge(){
  35. return age;
  36. }
  37. }
  38. public class VectorDemo {

  39. public static void main(String[] args) {
  40. TreeSet ts=new TreeSet();
  41. //TreeSet会为元素进行排序,但是要求元素具备比较性
  42. //这里是对象没有比较性,所以要让他具备比较性
  43. ts.add(new Student("lisi04",24));
  44. ts.add(new Student("lisi01",20));
  45. ts.add(new Student("lisi03",22));
  46. ts.add(new Student("lisi02",21));
  47. ts.add(new Student("lisi05",24));

  48. Iterator it=ts.iterator();
  49. while(it.hasNext()){
  50. Student s=(Student)it.next();
  51. sop(s.getName()+"****"+s.getAge());

  52. }
  53. }

  54. public static void sop(Object obj){
  55. System.out.println(obj);
  56. }

  57. }</P>
复制代码

Comparator:让集合自身具备比较性,需要定义一个实现了Comparator接口的比较器,并覆盖compare方法,并将类该对象作为实际参数传递给TreeSet集合的构造函数
如代码:
  1. package doo;
  2. /*
  3. * 练习:按照字符串长度排序
  4. * 字符串本身具备比较性,但是他的比较方式不是所需要的
  5. * 这时就能使用比较器
  6. */
  7. import java.util.*;
  8. public class VectorDemo {

  9. public static void main(String[] args) {
  10. TreeSet ts=new TreeSet(new StrLenCompare());//将类该对象作为实际参数传递给TreeSet集合的构造函数
  11. ts.add("abd");
  12. ts.add("ab");
  13. ts.add("aaa");
  14. ts.add("acdsd");
  15. ts.add("acvd");
  16. ts.add("a");
  17. Iterator it=ts.iterator();
  18. while(it.hasNext()){
  19. sop(it.next());
  20. }
  21. }

  22. public static void sop(Object obj){
  23. System.out.println(obj);
  24. }

  25. }
  26. class StrLenCompare implements Comparator{
  27. public int compare(Object o1,Object o2){
  28. String s1=(String)o1;
  29. String s2=(String)o2;
  30. // if(s1.length()>s2.length())
  31. // return 1;
  32. // if(s1.length()==s2.length())
  33. // return 0;
  34. int num=new Integer(s1.length()).compareTo(new Integer(s2.length()));
  35. if(num==0)
  36. return s1.compareTo(s2);
  37. return num;
  38. }

  39. }
复制代码
第二种方式较为灵活。而且当两种方式都存在时,以比较器为主



作者: 24岁???    时间: 2014-6-30 15:36
燿陚√揚葳 发表于 2014-6-30 12:29
Comparable:让元素自身具备比较性,需要元素对象实现Comparable接口,覆盖compareTo方法

如下面的代码: ...

直接比较元素,复写compareTo   而定义比较器就要复写compare可以这么理解吧,也就是说compareTo就是提供成员比较的,而compare是进行对象比较么?但是这个compare也可以参与到元素的比较之中,可以这么理解么
作者: 215041631    时间: 2014-6-30 16:42
本帖最后由 215041631 于 2014-6-30 16:43 编辑

刚看完这个视频,说下我的理解。
TREESET两种自定义排序的实现方式
从功能上说,其实他们都是一样的。用谁都可以实现,只不过实现的方式不一样。
compareTo()需要在自定义类中实现(implements)Comparable接口并在类中重写compareTo()方法形成自己的比较方法。
当自定义类中没有我们自定义的compareTo(),或者具备的比较性(也就是自定义类中的comparaTo())不是所需要的时候,我们用comparable接口来扩展我们的比较方式,这会比直接到程序里边修改我们的代码方式好,并不是说不能去修改
作者: 燿陚√揚葳    时间: 2014-6-30 17:00
本帖最后由 燿陚√揚葳 于 2014-6-30 17:01 编辑
24岁??? 发表于 2014-6-30 15:36
直接比较元素,复写compareTo   而定义比较器就要复写compare可以这么理解吧,也就是说compareTo就是提供 ...


Comparable让元素自身具备比较性,TreeSet底层就是调用这个方法进行比较的,你里面存放String类型对象他就可以比较,是因为String复写了compareTo方法,可如果元素是一个自定义类的对象的话,它是没有比较性的,也就是说集合在给这个对象进行比较时它都没有compareTo这个比较的方法,集合底层在调用这个方法,所以要让他实现Comparable,让元素具备比较性,其实就是为了复写compareTo方法,让TreeSet集合调用
这种比较方式也称为元素的自然顺序,或者叫做默认顺序

Comparator让集合具备比较性,将一个实现了Comparator接口的类的对象传递给TreeSet,就是告诉TreeSet集合让他不要按照默认方式比较,按照比较器比较,这就是让集合自身具备比较性

你可以理解成一个是默认的比较方式,一个是自定义的比较方式,但是两种方法都是让对象元素具备某种比较性


作者: wisely    时间: 2014-6-30 19:34
自建类,如Person,Student本身是不具备比较性的,因为Person与Person之间,Student与Student之间没法比,比啥?身高,年龄,学号?你没说程序就不知道,想让Person、Student具备比较性,这两个class就必须实现Comparable接口,可以查一下某些具备比较性的类,如String、Integer,它们就是实现了Comparable,这才具备了比较性。而在Comparable接口中,只有一个compareTo()方法,既然继承了Comparable接口,那么就要复写它。
而如果你自建的类没有比较性(也就是没有继承Comparable接口),那么只能让集合类中的对象具备比较性,这时候就需要看一下集合类中的构造方法。TreeSet类中的构造方法,其中有一种是可以传入一个比较器(Comparator),既然要传入比较器,自然要新建一个比较器类,这样才能new对象。既然是新建比较器对象,那么不实现Comparator接口怎么行。类Comparator中比较性的方法是compare,复写了之后就行。
第二种灵活,但一般来说,你在自建类时,一定要想到比较性,第二种是在更新换代时才用。所以来说,自建类时,要继承Comparable,复写其中的CompareTo()方法。Comparator接口是补救措施(这个说法不太准确,明白意思吧。)

从字面上看,Comparable是形容词,可比较的。而Comparator是名词,比较器。




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2