您的位置:程序门 -> java -> j2se / 基础类



要求接口comparable中compareto反对称的问题


[收藏此页] [打印本页]选择字色:背景色:字体:[][][]


要求接口comparable中compareto反对称的问题[已结贴,结贴人:cquaone]
发表于:2007-03-23 15:59:37 楼主
一下是一个例子:

其中employee为manager的超类
二者都实现了接口comparable,即  

public   interface   comparable
{
    int   compareto(object   otherobject);
}

下面是manager中实现的compareto方法
public   int   compareto(object   otherobject)
{
    if(otherobject   instanceof   manager)
    {
        manager   other=(manager)otherobject;
        (略)
    }
   
    else   if(otherobject   instanceof   employee)
    {
        return   1;
    }
   
    else
        return   -((comparable)otherobject).compareto(this);
}

manager的compareto方法之所以这样写是因为java语言标准中对compareto方法有 "反对称 "原则的要求,
大家能说出,为什么这样写可以满足这样的原则吗?
我主要是对最后一句在这个过程中所起的作用不清楚
发表于:2007-03-23 16:14:401楼 得分:50
反对称就是   两个对象比较时   应该满足
 
a   ,   b   的意义如下

int     a   =   x.compareto(y)  

  int   b   =     y.compareto(x)

  a   和   b的符号   正负性   相反   用数学表示就是   a*b   <=0  


很显然  
   
return   -((comparable)otherobject).compareto(this);

这样就可确保   再不知道otherobject   怎么定义compareto的时候   肯定有两者符号相反
发表于:2007-03-23 16:17:142楼 得分:0
反对称的原则,是说
如果a> b,那么b <a,如果a <b,那么b> a

也就是说
a.compareto(b)=-b.compareto(a)
假设a,b都是comparable的实例
发表于:2007-03-23 16:23:123楼 得分:49
代码有待改进
public   int   compareto(object   otherobject)
{
    if(otherobject   instanceof   manager)
    {
        manager   other=(manager)otherobject;
        (略)
    }
   
    else   if(otherobject   instanceof   employee)
    {
        return   1;
    }
   
    else   if(otherobject   instanceof   comparable)
        return   -((comparable)otherobject).compareto(this);
    else
        throw   new   java.lang.illegalargumentexception();
}
如果另外一个对象定义了对此类的compareto方法,但是此类没有处理对应的类型,如果不这么写
就会出现
a.compareto(b)   和   b.compareto(a)不反对称的情况
发表于:2007-03-23 16:31:094楼 得分:0
但是这样写存在着死循环的风险
参考以下代码

class   a   implements   comparable
{
int   a;

public   int   compareto(object   o)   {
if(o   instanceof   a)
{
a   a1=(a)o;
if(a> a1.a)
return   1;
else   if(a <a1.a)
return   -1;
return   0;
}
else   if(o   instanceof   comparable)
{
return   -((comparable)o).compareto(this);
}
else
throw   new   java.lang.illegalargumentexception();
}
}
class   b   implements   comparable
{
int   b;

public   int   compareto(object   o)   {
if(o   instanceof   b)
{
b   b1=(b)o;
if(b> b1.b)
return   1;
else   if(b <b1.b)
return   -1;
return   0;
}
else   if(o   instanceof   comparable)
{
return   -((comparable)o).compareto(this);
}
else
throw   new   java.lang.illegalargumentexception();
}
}

a   a=new   a();
b   b=new   b();
a.compareto(b)将造成死循环
发表于:2007-03-23 16:42:505楼 得分:0
interpb   看着你的解释我顿时开了窍

((comparable)otherobject).compareto(this);
相当于otherobject对象调用compareto时的otherobject.compareto(amanager)

用在manager类中,将amanager换为this,再加上负号,就相当于一个 "反引用 "(我自己造的词),
这样必然造成两次结果是正负相反的

没想到redduke1202又提出了新问题,谢谢你这么用心:)

都加分1!
发表于:2007-03-23 16:45:486楼 得分:0
还是等大家对我的理解和redduke的疑问进行确认后再结贴吧
这样有助于讨论问题:)
发表于:2007-03-23 17:01:127楼 得分:0
接上面的代码
测试结果
exception   in   thread   "main "   java.lang.stackoverflowerror
at   a.compareto(test.java:24)
at   b.compareto(test.java:46)
at   a.compareto(test.java:24)
at   b.compareto(test.java:46)
at   a.compareto(test.java:24)
at   b.compareto(test.java:46)
at   a.compareto(test.java:24)
at   b.compareto(test.java:46)
at   a.compareto(test.java:24)
                  (此处省略5000行)
发表于:2007-03-23 17:07:188楼 得分:0
redduke  
你真厉害
发表于:2007-03-23 17:12:469楼 得分:1
up
发表于:2007-03-23 17:14:3710楼 得分:0
这个例子是书上的,我想书上应该是在假设otherobject中已实现comparable接口的前提下给出该代码片断的

不知道这样的前提是不是就不会造成死循环的存在
发表于:2007-03-23 17:15:5511楼 得分:0
楼主的例子引自core   java   第6版   第201页
发表于:2007-03-23 17:16:4012楼 得分:0
在反对称和存在潜在bug的风险中,比较难取舍
发表于:2007-03-23 17:18:0413楼 得分:0
就是实现comparable才存在潜在的风险
如果不实现comparable,则更增加   classcastexception,类型转换异常了
发表于:2007-03-23 17:20:4214楼 得分:0
你的意思是反对称这个原则本身就有一定的缺陷?
发表于:2007-03-23 17:24:3615楼 得分:0
那么,程序之所以这样写((comparable)otherobject).compareto(this);
是因为otherobject是以object类型传进来的,为了调用otherobject自己的compareto,就需要把它转换为本来的类型,但又不知道它具体是什么类型,所以用comparable类型转换就可以达到将otherobject转换为其本来类型进而调用自身compareto方法的效果?


这是我在另一个帖子问你的问题,你没来的及回答还.
发表于:2007-03-23 17:38:4216楼 得分:0
看我上面的代码
需要先判断一下,传入的参数是否实现了comparable接口
如果实现了,就用反对称的写法,如果没实现,则抛出异常


快速检索

最新资讯
热门点击