为了账号安全,请及时绑定邮箱和手机立即绑定

“比较法违反了它的一般合同!”

“比较法违反了它的一般合同!”

慕姐8265434 2019-05-31 16:57:58
“比较法违反了它的一般合同!”有人能简单地解释一下吗?为什么这段代码会抛出一个异常,“比较方法违反了它的一般契约!”,以及如何修复它?private int compareParents(Foo s1, Foo s2) {     if (s1.getParent() == s2) return -1;     if (s2.getParent() == s1) return 1;     return 0;}
查看完整描述

3 回答

?
扬帆大鱼

TA贡献1799条经验 获得超9个赞

你的比较器不是传递性的。

放任A做父母B,和B做父母C..自A > BB > C,那么一定是这样的A > C..但是,如果您的比较器是在AC,它将返回零,意思是A == C..这违反了契约,因此引发异常。

库能检测到这一点并让您知道这一点,而不是行为不规范,这是相当不错的。

中满足传递性要求的一种方法compareParents()是遍历getParent()链而不是只看直接的祖先。


查看完整回答
反对 回复 2019-05-31
?
青春有我

TA贡献1784条经验 获得超8个赞

就因为这就是我在谷歌搜索这个错误时得到的,我的问题是

if (value < other.value)
  return -1;else if (value >= other.value)
  return 1;else
  return 0;

这个value >= other.value(显然)应该是value > other.value这样你就可以用相同的对象返回0。


查看完整回答
反对 回复 2019-05-31
?
撒科打诨

TA贡献1934条经验 获得超2个赞

违反合同通常意味着比较国在比较对象时没有提供正确或一致的值。例如,您可能希望执行字符串比较,并强制空字符串排序到最后:

if ( one.length() == 0 ) {
    return 1;                   // empty string sorts last}if ( two.length() == 0 ) {
    return -1;                  // empty string sorts last                  }return one.compareToIgnoreCase( two );

但这会忽略一和二都是空的情况-在这种情况下,返回错误的值(1,而不是0,以显示匹配),比较器报告为违规。它应该写成:

if ( one.length() == 0 ) {
    if ( two.length() == 0 ) {
        return 0;               // BOth empty - so indicate
    }
    return 1;                   // empty string sorts last}if ( two.length() == 0 ) {
    return -1;                  // empty string sorts last                  }return one.compareToIgnoreCase( two );


查看完整回答
反对 回复 2019-05-31
  • 3 回答
  • 0 关注
  • 419 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号