【问题标题】:Comparison method violates its general contract比较法违反其总合同
【发布时间】:2015-07-03 07:11:44
【问题描述】:

我已经在 class 上实现了 Comaprable ,它给我的比较方法违反了它的一般合同! , 由于有些值返回为 null , 代码如下

公共静态比较器名称比较器 = 新的比较器() {

    public int compare(JSONReceiptList rName1, JSONReceiptList rName2) {
        if(rName1.retailer!=null || rName2.retailer!=null) {


            if(rName1.retailer==null||rName2.retailer==null) {

                return 0;
            }
            else
            {
                if(rName1.retailer.retailerName==null ||rName2.retailer.retailerName==null ) {
                    return 0;
                }
                else
                {String Name1 = rName1.retailer.getRetailerName().toUpperCase();
                    String Name2 = rName2.retailer.getRetailerName().toUpperCase();
                    return Name1.compareTo(Name2);

                }
            }
            //ascending order

        }
        else
        {
            return 0;
        }

    }

};

【问题讨论】:

  • 是的,您的比较违反了合同。如果你有xyz这样x < z(没有null)但y有空值,所以compare(x, y)是0,compare(y, z)是0。从根本上说,你需要重新考虑值为空时的结果。

标签: java android


【解决方案1】:

确实违反了合同。 来自Comparator API

从比较契约直接得出,商是 S 上的等价关系,而强加的排序是 S 上的全序。

total order 是可传递的、反对称的和总的。

但是您的代码强加的顺序是不可传递的。如果 x 和 y 具有非空值并且 x

比较(x,z) = 0。比较(y,z) = 0。 因此,根据传递属性,compare(x,y) 应该为零,但事实并非如此。

一种可能的解决方案是将空值视为最低值。

  public int compare(JSONReceiptList rName1, JSONReceiptList rName2) {
      boolean r1IsNull = rName1.retailer==null || rName1.retailer.retailerName==null;
      boolean r2IsNull = rName2.retailer==null || rName2.retailer.retailerName==null;
      if ( r1IsNull && r2IsNull )
          return 0;
      else if ( r1IsNull  && !r2IsNull )
          return -Integer.MAX_VALUE;
      else if ( !r1IsNull && r2IsNull )
          return Integer.MAX_VALUE;
      else // Both are non null
      {
            String name1 = rName1.retailer.getRetailerName().toUpperCase();
            String name2 = rName2.retailer.getRetailerName().toUpperCase();
            return name1.compareTo(name2);
      }
  }

【讨论】:

  • 感谢您的评论,我得到了解决方案,实际上空值会造成问题,name1 和 name2 当两者都为空时
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多