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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© jacoblx 中级黑马   /  2014-11-1 06:24  /  2891 人查看  /  22 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 jacoblx 于 2014-11-1 06:31 编辑

假设一个父类Person,一个子类Student,两者可以拥有不同的自然排序方法compareTo吗?比如Person类按姓名排序,Student类按成绩排序。

如果可以的话,子类如何实现compareTo方法?需要再次实现Comparable接口吗?泛型怎么写?

先谢过了

例如
public class Person implements Comparable<Person>{
       private String name;
       private int age;
       public Person(String name, int age) {
              super();
              this.name = name;
              this.age = age;
       }
      
       @Override
       public int compareTo(Persono) {
              int margin = this.name.compareTo(o.name);
              return margin == 0 ? this.age - o.age : margin;
       }
}
public class Student extends Person /*这里需要再次实现Comparable接口吗?*/{
       private int mark;
       public Student(String name, int age, int mark) {
              super(name, age);
              this.mark = mark;
       }
       //这里没办法覆盖父类的comparaTo方法,因为参数类型不一样
       public int compareTo(Studento) {
              int margin = this.mark - o.mark;
              return margin == 0 ? super.compareTo((Person)o): margin;
       }
}

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1 赞一个!

查看全部评分

22 个回复

倒序浏览
可以new一个Collator,复写 int compare(Object o1, Object o2)   ,写一个单独的比较规则
回复 使用道具 举报
D.reamJA 发表于 2014-11-1 06:39
可以new一个Collator,复写 int compare(Object o1, Object o2)   ,写一个单独的比较规则 ...

当然用比较器可以解决问题。难道在父子类上分别实现不同的自然排序方法是不可行的吗?
回复 使用道具 举报
没试过,楼主可以试试子父类都实现Comparable。复写CompareTo方法,
实践才是检验真理的唯一方法
回复 使用道具 举报
楼主可以试试把泛型改成“? extends Person ”, student的方法传入参数仍为 Person o,我没试过,期待你试过的结果。。。。。:D
回复 使用道具 举报
Eagle 发表于 2014-11-1 09:16
没试过,楼主可以试试子父类都实现Comparable。复写CompareTo方法,
实践才是检验真理的唯一方法 ...

这个不行
提示:
The interface Comparable cannot be implemented more than once with different arguments: Comparable<Person> and Comparable<Student>
回复 使用道具 举报
游泳的猫 发表于 2014-11-1 09:49
楼主可以试试把泛型改成“? extends Person ”, student的方法传入参数仍为 Person o,我没试过,期待你 ...

谢谢。
这样的话,Student就不能按分数排序了,因为Person类没这个属性的。。。
回复 使用道具 举报
jacoblx 发表于 2014-11-1 22:03
谢谢。
这样的话,Student就不能按分数排序了,因为Person类没这个属性的。。。 ...

你好,我弄错了,我又重新做了一次,我测试结果是满足,你看看行不?。。。。。。。import java.util.Iterator;
import java.util.TreeSet;

public class TreeSetDemo {
        public static void main(String[] args){
                TreeSet<Student> ts=new TreeSet<Student>();
                ts.add(new Student("lisi01",04,98));
                ts.add(new Student("lisi02",03,85));
                ts.add(new Student("lisi03",02,72));
                ts.add(new Student("lisi04",01,88));
                for (Iterator it=ts.iterator();it.hasNext() ; )
                {
                        Student s=(Student)it.next();
                        System.out.println(s.getName()+"....."+s.getAge()+"....."+s.getMark());
                }
        }
       

}
class Person implements Comparable{
        private String name;
    private int age;
    public Person(String name, int age) {
           super();
           this.name = name;
           this.age = age;
    }
        @Override
        public int compareTo(Object obj){
                Person person=(Person)obj;
                int margin = this.name.compareTo(person.name);
        return margin == 0 ? this.age - person.age : margin;
        }
        public String getName() {
                return name;
        }
        public int getAge() {
                return age;
        }
       
}

class Student extends Person/*这里需要再次实现Comparable接口吗?   我没有覆盖*/{
    private int mark;
    public Student(String name, int age, int mark) {
           super(name, age);
           this.mark = mark;
    }
  //这样覆写了
    public int compareTo(Object obj) {
                    Student stu=(Student)obj;
           int margin = this.mark - stu.mark;
           return margin == 0 ? super.compareTo((Person)stu): margin;
    }
        public int getMark() {
                return mark;
        }

}

评分

参与人数 1技术分 +1 收起 理由
杨佳名 + 1

查看全部评分

回复 使用道具 举报
游泳的猫 发表于 2014-11-1 23:06
你好,我弄错了,我又重新做了一次,我测试结果是满足,你看看行不?。。。。。。。import java.util.Ite ...

我试了下,确实可以,谢谢

不过没用泛型会有警告,开发的时候这样使不太好吧。

我觉得最终可能只有父类使用实现Comparable的方法,而子类如需要特殊比较方式,使用比较器是比较稳妥的方法。
回复 使用道具 举报
应该是可以的 你在比较传入的元素之前 做一个类型判断 是学生 就用A数学比较 是老师就用B数学 比较
回复 使用道具 举报
jacoblx 发表于 2014-11-2 08:47
我试了下,确实可以,谢谢

不过没用泛型会有警告,开发的时候这样使不太好吧。

对,确实不安全,还是比较器靠谱一些{:3_57:}
回复 使用道具 举报
可以用泛型的 进了比较方法再按类型区分对待
  1. package com.itheima.io;

  2. import java.util.TreeSet;

  3. class Test
  4. {
  5.         public static void main(String[] args)
  6.         {
  7.                 TreeSet<Student> stu = new TreeSet<Student>();
  8.                 stu.add(new Student("stu3",21));
  9.                 stu.add(new Student("stu2",22));
  10.                 stu.add(new Student("stu1",23));
  11.                 System.out.println(stu);
  12.                 TreeSet<Person> per = new TreeSet<Person>();
  13.                 per.add(new Person("per3",21));
  14.                 per.add(new Person("per2",22));
  15.                 per.add(new Person("per1",23));
  16.                 System.out.println(per);
  17.                
  18.         }
  19. }
  20. class Person implements Comparable<Person>
  21. {
  22.         String name;
  23.         int age;
  24.         Person(String name,int age)
  25.         {
  26.                 this.name = name;
  27.                 this.age = age;
  28.         }
  29.         public int compareTo(Person p)
  30.         {
  31. //                if(p.getClass()==Person.class)
  32.                 if(p.getClass()==Student.class)
  33.                         return this.name.compareTo(p.name);
  34.                 else
  35.                         return this.age - p.age;
  36.         }
  37.         public String toString()
  38.         {
  39.                 return name+"="+age;
  40.         }
  41. }
  42. class Student extends Person
  43. {
  44.         String name;
  45.         int age;
  46.         Student(String name,int age)
  47.         {
  48.                 super(name,age);
  49.                 this.name = name;
  50.                 this.age = age;
  51.         }
  52.         public String toString()
  53.         {
  54.                 return name+"="+age;
  55.         }
  56. }
复制代码
回复 使用道具 举报
可以
public class TreeSetDemo {
               
        public static void main(String[] args) {

                TreeSet<Person> treeSet=new TreeSet<Person>(/*new CompareByAge()*/);
                treeSet.add(new Person("zhangSan",21));
                treeSet.add(new Person("wangWu",29));
                treeSet.add(new Person("zhaoliu",21));
               
                TreeSet<Student> treeSet2=new TreeSet<Student>(/*new CompareByAge()*/);
                treeSet2.add(new Student("zhangSan2",12,100));
                treeSet2.add(new Student("wangWu3",29,30));
                treeSet2.add(new Student("zhaoliu4",21,50));
               
                boolean bool=treeSet.addAll(treeSet2);
                System.out.println(bool);
                System.out.println("size:"+treeSet.size());
                //进行迭代
                Iterator it=treeSet2.iterator();
               
                while(it.hasNext())
                {
                        System.out.println(it.next());
                }
        }
       
}

package day16_17.cn.itcast.bean;

import java.util.Comparator;

public class Person  implements Comparable<Person>{
        protected String name;
        protected int age;

        public Person() {
                super();
                // TODO 自动生成的构造函数存根
        }

        public Person(String name, int age) {
                super();
                this.name = name;
                this.age = age;
        }

        public String getName() {
                return name;
        }

        public void setName(String name) {
                this.name = name;
        }

        public int getAge() {
                return age;
        }

        public void setAge(int age) {
                this.age = age;
        }

       
        @Override
        public int hashCode() {
                final int prime = 31;
                int result = 1;
                result = prime * result + age;
                result = prime * result + ((name == null) ? 0 : name.hashCode());
                return result;
        }

        @Override
        public boolean equals(Object obj) {
                if (this == obj)
                        return true;
                if (obj == null)
                        return false;
                if (getClass() != obj.getClass())
                        return false;
                Person other = (Person) obj;
                if (age != other.age)
                        return false;
                if (name == null) {
                        if (other.name != null)
                                return false;
                } else if (!name.equals(other.name))
                        return false;
                return true;
        }

        @Override
        public int compareTo(Person o) {
               
                //比较年龄
                int temp=this.age-o.getAge();
                //如果年龄相同,就比较姓名
                return temp==0?this.name.compareTo(o.getName()):temp;
        }

        @Override
        public String toString() {
                return "Person [name=" + name + ", age=" + age + "]";
        }
}

package day16_17.cn.itcast.bean;

public class Student extends Person{
        private int mark;
       
        public Student() {
                super();
                // TODO 自动生成的构造函数存根
        }

        public Student(String name, int age,int mark) {
                super(name, age);
                this.mark=mark;
        }

        public int getMark() {
                return mark;
        }

        public void setMark(int mark) {
                this.mark = mark;
        }
       
       
        public int compareTo(Student o){
                int temp=this.mark-o.getMark();
                return temp==0?super.compareTo(o):temp;
        }

        @Override
        public String toString() {
                return "Student [mark=" + mark + ", name=" + name + ", age=" + age
                                + "]";
        }


}
回复 使用道具 举报
本帖最后由 jacoblx 于 2014-11-4 00:15 编辑
zhangyangLengen 发表于 2014-11-2 19:56
可以
public class TreeSetDemo {
               

谢谢

你的代码中学生的比较仍然是使用从Person类继承来的compareTo方法,是按年龄排序的,你把第一个学生的年龄改为25就可以看出来,排序就变了。
回复 使用道具 举报
子类不需要写 实现Compareble借口因为父类已经实现了  你已经继承了父类,如果你需要子类有特殊的比较方法只需要  覆写 compareTo方法即可
回复 使用道具 举报
可能应该单独的写个Comparatpr <Student> 的实现类
回复 使用道具 举报
子类明明就覆盖了,怎么就没有调用子类的啊
回复 使用道具 举报
wf111sxwf 发表于 2014-11-4 13:43
子类不需要写 实现Compareble借口因为父类已经实现了  你已经继承了父类,如果你需要子类有特殊的比较方法 ...

问题就在于如何覆盖,因为父类传入的比较参数是Person类型,而子类需要比较的是自己特有的属性,需要传入Student类型的参数,参数不一样就没办法覆盖。我目前想到的比较好的方法是子类使用比较器来实现。
回复 使用道具 举报
zhangyangLengen 发表于 2014-11-4 23:19
可能应该单独的写个Comparatpr  的实现类

不错,我也是这个想法,comparaTo方法是没办法覆盖父类的。
回复 使用道具 举报
zhangyangLengen 发表于 2014-11-4 23:20
子类明明就覆盖了,怎么就没有调用子类的啊

谢谢。

因为参数表不一样,所以没有覆盖,而是重载了。
回复 使用道具 举报
12下一页
您需要登录后才可以回帖 登录 | 加入黑马