A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

看着JDK做出了基础测试题目,用这两种方式都实现了,却不知道他们到底有什么区别,很多的类都实现了comparable接口,而comparator实现类很少,就这区别吗?望大神解答。谢谢。。。下面是代码:
实现comparable接口的:
  1. package com.itheima;

  2. import java.util.Iterator;
  3. import java.util.TreeSet;

  4. public class Test10 {
  5.         public static void main(String[] args) {
  6.                 //声明创建TreeSet集合泛型为Student
  7.                 TreeSet<Student> set = new TreeSet<Student>();
  8.                 //声明创建五个student并加入set集合
  9.                 Student stu1 = new Student("小明", 23, 98.5);
  10.                 Student stu2 = new Student("小红", 24, 45.6);
  11.                 Student stu3 = new Student("小强", 25, 84.2);
  12.                 Student stu4 = new Student("小刚", 26, 84.2);
  13.                 Student stu5 = new Student("小松", 23, 98);
  14.                 set.add(stu1);
  15.                 set.add(stu2);
  16.                 set.add(stu3);
  17.                 set.add(stu4);
  18.                 set.add(stu5);
  19.                 System.out.println("set大小:" + set.size());
  20.                 //调用所定义的对set集合的输出函数
  21.                 Myout(set);
  22.         }

  23.         public static void Myout(TreeSet<Student> set) {
  24.                 //迭代set集合
  25.                 Iterator<Student> it = set.iterator();
  26.                 //取出迭代器中的元素
  27.                 while (it.hasNext()) {
  28.                         Student stu = (Student) it.next();
  29.                         System.out.println(stu.toString());
  30.                 }

  31.         }

  32. }
  33. /*
  34. * 定义Student类,并继承Comparable并实现compareto()方法
  35. * 在此我直接将泛型加入,省去compareto()中的强转
  36. *
  37. */
  38. class Student implements Comparable<Student>{
  39.         private String name;
  40.         private int age;
  41.         private double score;

  42.         public Student() {
  43.         }
  44.         //增加带参数构造器方便添加数据
  45.         public Student(String name, int age, double score) {
  46.                 super();
  47.                 this.name = name;
  48.                 this.age = age;
  49.                 this.score = score;
  50.         }
  51.         //增加get set 方法
  52.         public String getName() {
  53.                 return name;
  54.         }
  55.         public void setName(String name) {
  56.                 this.name = name;
  57.         }
  58.         public int getAge() {
  59.                 return age;
  60.         }
  61.         public void setAge(int age) {
  62.                 this.age = age;
  63.         }
  64.         public double getScore() {
  65.                 return score;
  66.         }
  67.         public void setScore(double score) {
  68.                 this.score = score;
  69.         }
  70.         //覆盖compareTo()方法,定义出自己所需的情况
  71.         @Override
  72.         public int compareTo(Student o) {
  73.                 Student stu = o;
  74.                 //下面几个if else 语句实现了先通过分数进行排序和年龄进行排序
  75.                 //如果两者都相同则通过姓名进行排序。
  76.                 //返回的-1、1和0也可以是其它的证书或者负数
  77.                 if (this.score < stu.score)
  78.                         return (int) -1;
  79.                 else if (this.score > stu.score)
  80.                         return 1;
  81.                 else if (this.age > stu.age)
  82.                         return 1;
  83.                 else if (this.age < stu.age)
  84.                         return -1;
  85.                 else if (this.score == stu.score && this.age == stu.age)
  86.                         //分数年龄相同则返回姓名的字典顺序差。
  87.                         return this.name.compareTo(stu.name);
  88.                 return 0;
  89.         }
  90.         //覆盖toString()方法方便调试和显示
  91.         @Override
  92.         public String toString() {
  93.                 return "Student [age=" + age + ", name=" + name + ", score=" + score
  94.                                 + "]";
  95.         }

  96. }
复制代码
实现comparator接口的
  1. package com.itheima;

  2. import java.util.Comparator;
  3. import java.util.Iterator;
  4. import java.util.TreeSet;

  5. public class Test10 {

  6.         /**
  7.          * 10、声明类Student,包含3个成员变量:name、age、score,创建5个对象装入TreeSet,
  8.          * 按照成绩排序输出结果(考虑成绩相同的问题)。
  9.          */
  10.         public static void main(String[] args) {
  11.                 //声明创建TreeSet集合泛型为Student
  12.                 TreeSet<Student> set = new TreeSet<Student>(new myStudentComparactor());
  13.                 //声明创建五个student并加入set集合
  14.                 Student stu1 = new Student("小明", 23, 98.5);
  15.                 Student stu2 = new Student("小红", 24, 45.6);
  16.                 Student stu3 = new Student("小强", 25, 84.2);
  17.                 Student stu4 = new Student("小刚", 26, 84.2);
  18.                 Student stu5 = new Student("小松", 23, 98);
  19.                 set.add(stu1);
  20.                 set.add(stu2);
  21.                 set.add(stu3);
  22.                 set.add(stu4);
  23.                 set.add(stu5);
  24.                 System.out.println("set大小:" + set.size());
  25.                 //调用所定义的对set集合的输出函数
  26.                 Myout(set);
  27.         }

  28.         public static void Myout(TreeSet<Student> set) {
  29.                 //迭代set集合
  30.                 Iterator<Student> it = set.iterator();
  31.                 //取出迭代器中的元素
  32.                 while (it.hasNext()) {
  33.                         Student stu = (Student) it.next();
  34.                         System.out.println(stu.toString());
  35.                 }

  36.         }

  37. }

  38. class Student {
  39.         private String name;
  40.         private int age;
  41.         private double score;

  42.         public Student() {
  43.         }
  44.         //增加带参数构造器方便添加数据
  45.         public Student(String name, int age, double score) {
  46.                 super();
  47.                 this.name = name;
  48.                 this.age = age;
  49.                 this.score = score;
  50.         }
  51.         //增加get set 方法
  52.         public String getName() {
  53.                 return name;
  54.         }
  55.         public void setName(String name) {
  56.                 this.name = name;
  57.         }
  58.         public int getAge() {
  59.                 return age;
  60.         }
  61.         public void setAge(int age) {
  62.                 this.age = age;
  63.         }
  64.         public double getScore() {
  65.                 return score;
  66.         }
  67.         public void setScore(double score) {
  68.                 this.score = score;
  69.         }
  70.        
  71.        
  72.         //覆盖toString()方法方便调试和显示
  73.         @Override
  74.         public String toString() {
  75.                 return "Student [age=" + age + ", name=" + name + ", score=" + score
  76.                                 + "]";
  77.         }

  78. }
  79. //自定义排序器
  80. class myStudentComparactor implements Comparator<Student>{


  81.         @Override
  82.         public int compare(Student o1, Student o2) {
  83.                 if (o1.getScore() > o2.getScore())
  84.                         return (int) -1;
  85.                 else if (o1.getScore() < o2.getScore())
  86.                         return 1;
  87.                 else if (o1.getAge() > o2.getAge())
  88.                         return 1;
  89.                 else if (o1.getAge() < o2.getAge())
  90.                         return -1;
  91.                 else if (o1.getScore() == o2.getScore() && o1.getAge() == o2.getAge())
  92.                         return o1.getName().compareTo(o2.getName());
  93.                 return 0;
  94.         }
  95.        
  96. }
复制代码



32 个回复

倒序浏览
好恐怖的代码,完全看不懂啊
回复 使用道具 举报
飘过的云 发表于 2015-5-20 23:54
好恐怖的代码,完全看不懂啊

是我写的太乱吗?:o
回复 使用道具 举报
今天学了,两种 方法都可以实现,采用第二种方法更合理些,它更符合面向对象的思想。
回复 使用道具 举报
Comparator相当于过滤器  你来啥对象 都通过这个过滤掉
comparable对象本身自定义的比较器
回复 使用道具 举报
tanzhixue 发表于 2015-5-21 00:15
Comparator相当于过滤器  你来啥对象 都通过这个过滤掉
comparable对象本身自定义的比较器 ...

学习了,都是大神啊
回复 使用道具 举报
王建伟 发表于 2015-5-21 00:03
是我写的太乱吗?

还没学到那,目前还在面向对象ING
回复 使用道具 举报
飘过的云 发表于 2015-5-21 00:28
学习了,都是大神啊

你是不是0508的?哪位?看你笔记和我的都差不多一样的
回复 使用道具 举报
当TreeSet创建对象的时候使用第一种也就是无参构造函数的时候,如果不去实现Comparable接口的话,会报一个类型转换异常的错误,因为TreeSet这种集合本身是不保证迭代顺序的但是它会默认给存入的元素通过魔种方式排序,而Set类的集合元素都是要保证唯一性的,所以TreeSet使用无参构造的时候必须实现Comparable接口重写里面的方法,根据返回值来给写入的元素排序,如果返回值是0那么只添加一个元素,如果元素为正,Java会认为所有元素都不相等会全部添加进去而且是正序的,如果返回值是负数也会全部添加但是是倒序的。
回复 使用道具 举报
而TreeSet使用带参构造的时候,传入的就是一个Comparator比较器对象,比较器一般都是自己写的,但是必须得实现了Comparator接口的比较器对象,这样我们就通过了比较器来判断了排序条件,而且这样的好处是明显的,符合了开发中对修改关闭,对扩展开放的原则。如果要改变条件可以多些几个比较器文件,这样比较方便也比较安全。
回复 使用道具 举报 1 0
实现comprarable 是让元素自身具备比较性,实现了compatator的类是自定义的比较器啊,有时候即便你的元素自身具备了比较性,后期用的时候发现比较顺序不是你想要的,但是返回去改代码就不太现实,就可以根据现在的需求自定义比较器
回复 使用道具 举报
....一个是在定义函数的时候 让函数具备比较方法    一个是自定义的比较器
回复 使用道具 举报
andre 发表于 2015-5-21 00:13
今天学了,两种 方法都可以实现,采用第二种方法更合理些,它更符合面向对象的思想。 ...

是的,不污染要比较的类的代码了。。。
回复 使用道具 举报
tanzhixue 发表于 2015-5-21 00:15
Comparator相当于过滤器  你来啥对象 都通过这个过滤掉
comparable对象本身自定义的比较器 ...

恩恩,好像是这样。。。。
回复 使用道具 举报
想要那片海 发表于 2015-5-21 08:04
实现comprarable 是让元素自身具备比较性,实现了compatator的类是自定义的比较器啊,有时候即便你的元素自 ...

恩恩,这样啊。。。。现在只是看着jdk写了出来,看你们说的才发现这么多东西呢,呵呵,谢谢了
回复 使用道具 举报
志行 发表于 2015-5-21 08:51
....一个是在定义函数的时候 让函数具备比较方法    一个是自定义的比较器

恩恩,是的。。。。。。
回复 使用道具 举报
王连涛 发表于 2015-5-21 07:48
而TreeSet使用带参构造的时候,传入的就是一个Comparator比较器对象,比较器一般都是自己写的,但是必须得 ...

对修改关闭对扩展开放是什么啊?:(
回复 使用道具 举报
zdh 中级黑马 2015-5-21 16:31:01
18#
用自定义类实现Comparable接口,那么这个类就具有排序功能,Comparable和具体你要进行排序的类的实例邦定。而Comparator比较灵活,它没有和任何类绑定,实现它的自定义类仅仅定义了一种排序方式或排序规则。不言而喻,这种方式比较灵活。我们的要排序的类可以分别和多个实现Comparator接口的类绑定,从而达到可以按自己的意愿实现按多种方式排序的目的。Comparable——“静态绑定排序”,Comparator——“动态绑定排序”。
回复 使用道具 举报
我怎么觉得你是大神呢.亲
回复 使用道具 举报
嘎嘎鸭子 来自手机 中级黑马 2015-5-21 18:26:19
20#
Comparator相当于过滤器你来啥对象 都通过这个过滤掉
comparable对象本身自定义的比较器
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马