如何创建混合比较器?

时间:2015-04-01 20:14:46

标签: java comparator

我有一个表格,其中前两位数字是一年,接下来的3位数字是0到999之间的值,最后2个字符是2个alphaOnly字符。一些示例值:0,0,99001AG,99002FG,54001AG,54050AB,还有一些实例,其值仅为6位字符串SGP4DC。将有多个值为SGP4DC。 0是坏数据但我必须考虑它们用于测试目的。

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

现在我的排序目标是先按前2位数排序,以处理上述特殊情况。然后使用以下3位数字进行操作。最后只对最后2个字符进行字符串排序。最后,使用不以2位数字开头的值的字符串比较来跟进。

预期按升序排序的示例将是 0 0 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;
}

更新了代码***

我目前在桌面上看不到任何内容,而且我的比较方法违反了一般合同错误。

1 个答案:

答案 0 :(得分:1)

您应该为比较器编写单元测试以发现错误。您还应该更好地考虑代码,因为您的功能很难理解。首先,将产品代码分类为&#34; 0&#34;案件,包含年度的案件和无年案件。如果这两个代码不在同一个类中,则返回相应的结果。

如果它们属于同一类,则将特定比较分解为单独的函数,甚至单独的比较器。使用单独的比较器使它们更容易测试;单独的职能将难以证明是公开的。

我通过查看代码发现了一个错误:对于c.compare("0", "0"),当它返回-1时会返回0。除此之外,它很难说清楚。