2015-04-01 59 views
0

我有一张表,其中前两位数字是一年,后三位数字是介于0到999之间的一个值,最后2个字符是2个alphaOnly字符。一些示例值:0,0,99001AG,99002FG,54001AG,54050AB,还有一些情况下值只是一个6位的字符串SGP4DC。将会有多个值为SGP4DC的值。 0是不好的数据,但为了测试目的,我必须考虑它们。如何创建混合比较器?

特殊情况:由于是两位数年份,当按降序排序时,从1999年(例如99001A)启动的排序总是比2000年(例如06001A)排序为“更大”。特殊处理程序应确保00到56之间的任何项目的排序大于57到99之间的任何项目。

现在我的排序目标是首先按照前两位数字的顺序来处理上述特殊情况。然后用下面的3位数字进行跟踪。最后只是最后2个字符的字符串排序。最后,用字符串比较不要以2位数字开头的值。的升序预期排序

实施例将是 60001AG 60002FB 42001AG 42002GD APG4GP APG4GP

再次注意,如果2个前导数字是大于或等于57它代表1957年-1999。如果2位数字小于57,则代表2000-2056。

最后我的代码。注意我目前在表格中有一些虚假数据,其值为0.因此,我试图让它们比其他所有东西都少。我没有权力去除0,所以我试图在他们周围编码。 IE 0将始终显示在上面的排序列表之后。

@Override 
public int compare(String o1, String o2) { 
    if(o1.equals("0") && o2.equals("0")){ 
     return 0; 
    } 
    System.out.println("Comparing " + o1 + " and " + o2); 
    if (o1.length() == 1) { 
     return -1; 
    } 
    if (o2.length() == 1) { 
     return 1; 
    } 

    String o1year = null; 
    String o2year = null; 
    Integer obj1year; 
    Integer obj2year; 

    if (o1.length() >= 2) { 
     o1year = o1.substring(0, 2); 
    } 
    if (o2.length() >= 2) { 
     o2year = o2.substring(0, 2); 
    } 

    if (isInteger(o1year)) { 
     if (isInteger(o2year)) { 

      obj1year = Integer.parseInt(o1year); 
      obj2year = Integer.parseInt(o2year); 

      // handles years 2000 - 2056 being greater than anything from 
      // ##57-##99 
      if (obj1year < 57 && obj2year > 56) { 
       return 1; 
      } 
      if (obj1year == obj2year) { 

       int returnValue = compareIncriment(o1, o2); 
       if(returnValue == 0){ 
       return o1.compareToIgnoreCase(o2); 
       } 
       return returnValue; 

      } 
      if (obj1year > obj2year) { 
       return 1; 
      } else { 
       return -1; 
      } 

     } 
     return 1; 
    } 

    // object 2 starts with a 2 digit year and object 1 didnt 
    if (isInteger(o2year)) { 
     return -1; 
    } 

    // final return 
    return o1.compareToIgnoreCase(o2); 
} 

private int compareIncriment(String o1, String o2) { 
    // TODO Auto-generated method stub 
    int inc1; 
    int inc2; 
    if(isInteger(o1.substring(2, 4))){ 
     inc1 = Integer.parseInt(o1.substring(2, 4)); 
    }else if(isInteger(o1.substring(2, 3))){ 
     inc1 = Integer.parseInt(o1.substring(2, 3)); 
    }else{ 
     inc1 = Integer.parseInt(o1.substring(2, 2)); 
    } 

    if(isInteger(o2.substring(2, 4))){ 
     inc2 = Integer.parseInt(o2.substring(2, 4)); 
    }else if(isInteger(o2.substring(2, 3))){ 
     inc2 = Integer.parseInt(o2.substring(2, 3)); 
    }else{ 
     inc2 = Integer.parseInt(o2.substring(2, 2)); 
    } 

    return inc1 - inc2; 
} 

更新的代码***

我现在什么也看不到我的表,我得到一个比较法违反其总承包的错误。

+0

真的没有混合比较器这样的东西。对象是可以相互比较的,或者它们不是。关键是要指定特定类型项目的“自然排序”规则。如果您可以指定明确定义的规则,那么应该可以实现表达这些规则的算法。 – scottb 2015-04-01 20:21:34

回答

1

您应该为比较器编写单元测试以发现错误。你还应该更好地考虑你的代码,因为你的功能很难理解。首先,将产品代码分为“0”情况,年份情况和非年度情况。如果两个代码不在同一个类中,则返回相应的结果。

如果它们在同一个类中,则将具体的比较分解为单独的函数,甚至是单独的比较器。具有独立的比较器使得它们更容易测试;单独的职能很难证明是公开的。

我通过查看代码发现了一个bug:对于c.compare("0", "0"),它应返回0时返回-1。除此之外,真的很难说。

+0

表示感谢。在添加一些错误处理之后,它会调用Collections.Sort。我发现它抛出以下错误。 比较方法违反其总体合同。 – Jeremy 2015-04-10 17:59:38

+0

发现我错过了一些导致错误的不同情况。通过将其进一步分解成单独的部分,我能够看到它丢失了哪些情况。 – Jeremy 2015-04-13 15:02:22