黑马程序员技术交流社区
标题:
为什么,不同类型的对象相比较竟然相等呢?
[打印本页]
作者:
孙传磊
时间:
2013-3-13 12:59
标题:
为什么,不同类型的对象相比较竟然相等呢?
本帖最后由 孙传磊 于 2013-3-14 00:27 编辑
按照视频说要使类具有可比较性需要实现Comparable 接口,覆写compareto,hashCode,和equals方法
可是在练习的时候遇到一个这样的问题,当我传入两个不同Student的对象比较时结果是,false,不相等。实现了比较。
但是当我传入Student的子类ColStudent的对象和Student的对象比较时既然返回true,相等。
毕竟ColStudent的对象和Student的对象不是同一类型啊,为什么会相等呢?下面是我写得代码。
问题出在那呢?如何才能实现不同对象也能分辨出来?
class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name,int age){
this.name=name;
this.age=age;
}
public int hashCode() {
final int prime = 31;
return name.hashCode()+age*31;
}
public boolean equals(Object obj){
if(obj instanceof Student){
Student s=(Student)obj;
if(s.name.equals(this.name) && s.age==this.age){
return true;
}
}
return super.equals(obj);
}
public int compareTo(Student o) {
int num=new Integer(this.age).compareTo(new Integer(o.age));
if(num==0) return this.name.compareTo(o.name);
return num;
}
}
class ColStudent extends Student{
public ColStudent(String name, int age) {
super(name, age);
}
}
public class EqualsT {
public static void main(String[] args){
Student s=new Student("zhangsan", 12);
Student s1=new Student("wangwu", 12);
ColStudent c=new ColStudent("zhangsan", 12);
System.out.println((s.compareTo(s1))==0 ? true :false);
System.out.println((s.compareTo(c))==0 ? true :false);
}
}
输出结果是:
false
true
作者:
姓名长度不符
时间:
2013-3-13 19:26
比较对象是否相等的时候,用的是euqals方法(只要在实现map接口的时候才会调用hashcode方法,一般重写equals方法时最好重写hashcode方法),这里的equals方法应该是用object的equals,还是调用了hashcode方法,对象s和c的hashcode是相等的,所以是ture
新手想法,有错希望指正
作者:
赵亚威
时间:
2013-3-13 19:46
你的程序出自name上 compareTo设置的比较规则是比较name的 那么equals的比较方法就不用了 hashCode只用于map集合 所以第一个是false 第二个是true 因为继承 对象可以向上转型 也可以向下转型 这不是重点 想到了 就说说
作者:
陈丽莉
时间:
2013-3-13 22:20
不知是否解决了问题~ 请及时在论坛追问或者结贴~
作者:
付玉光
时间:
2013-3-13 23:36
本帖最后由 付玉光 于 2013-3-13 23:39 编辑
{:soso_e100:}
//老大,我真服了你了,你的题目和你提供的代码,根本就是两码事,
//也就是说,你提供的代码与你的题目没关系,不相干!
//为什么,不同类型的对象相比较竟然相等呢?
//①
//老大,API中不同类型的对象相比,是不会相等的(包装类除外,可自动拆装箱),
//除非你自定义类覆写了Object中的equals方法,
//自定义了比较相等的规则!你写的这个程序子父类中两个对象相比较是相等的,
//原因就是因为你自定义的子类没有自己特有的数据,
//没有覆写父类的equals方法(如果你写了是需要强转为子类类型的!)
//而是使用了父类的equals方法进行比较。所以它们比较的结果是相等的。
//ColStudent类中覆写父类的equals方法:
/*
public boolean equals(Object obj){
if(obj instanceof ColStudent){
ColStudent s=(ColStudent)obj;
if(s.getName() .equals(super.getName()) && s.getAge()==super.getAge()){
return true;
}
}
return false;
}
*/
//②你在程序中用:
//System.out.println((s.compareTo(s1))==0 ? true :false);
//System.out.println((s.compareTo(c))==0 ? true :false);
//以上的两条程序语句是在比较两个对象相等吗?
//不要搞笑了,好吧,你居然想用它来比较两对象是否相等,
//它只是说s 和 c 两对象或 s 和 s1 两对象中的两个成员属性的内容相同,
//是不能代替equals方法的,因为equals方法中是需要类型强转这一步的。
//它又不是TreeSet集合(可保证元素唯一是通过Comparable接口中的该方法)
//它只不过和equlas方法比较两对象的(代码程序)像罢了。
作者:
孙传磊
时间:
2013-3-14 00:17
付玉光 发表于 2013-3-13 23:36
//老大,我真服了你了,你的题目和你提供的代码,根本就是两码事,
//也就是说,你提供的代 ...
其实,之前我感觉你还是挺聪明的人的!不是自大的那种!是来解决问题的!!癌!
看清题目了:你的嘴巴很不饶人啊!
我拿一个Student对象和一个ColStudent对象的子类是一个类型吗?如果不是同一个类型为什么在equals方法处不能直接不允许它们相互比较,这里涉及到getClass()的应用。如果用getClass()是不是比instanceof好?
如果
/System.out.println((s.compareTo(s1))==0 ? true :false);
//System.out.println((s.compareTo(c))==0 ? true :false);
//以上的两条程序语句不能比较两个类是否相同,更是你来解决错误的了,如何用到 hashCode()和equals()来确定不是同一对象了?不然要你干吗?
作者:
许鑫星
时间:
2013-3-15 13:32
@Override
public int compareTo(Object o) {
if (o.getClass()==Student.class) {
Student s = (Student)o;
int num = new Integer(this.age).compareTo(new Integer(s.age));
if (num == 0)
return this.name.compareTo(s.name);
return num;
} else {
throw new RuntimeException("no cast");
}
}
复制代码
有是有办法,把student上的 Comparable<Student>泛型取消,改成class Student implements Comparable , 然后再复写compareTo方法,判断是否为同类型。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2