2015-04-01 2 views
0

У меня есть таблица, полная значений, где первые 2 цифры - год, следующие 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 цифры, чтобы позаботиться об этом специальном случае. Затем следуйте этим следующим трем цифрам. И, наконец, просто сортировка строки по последним 2 символам. И, наконец, последуйте за этим, сравнивая String значения, которые не начинаются с 2 числовых цифр.

Пример ожидаемых сортируются в порядке возрастания будет 60001AG 60002FB 42001AG 42002GD APG4GP APG4GP

Опять же, обратите внимание, если 2 первые цифры больше или равно 57 представляет 1957 -1999. И если две ведущие цифры меньше 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

ответ

1

Вы должны написать модульные тесты для вашего компаратора, чтобы обнаружить ошибки. Вы должны также улучшить свой код, потому что ваша функция очень трудно понять. Во-первых, классифицируйте код продукта в случае «0», случае, включенном в год, и в случае отсутствия года. Если два кода не находятся в одном классе, верните соответствующий результат.

Если они находятся в одном классе, учитывайте конкретные сравнения в отдельных функциях или даже отдельные компараторы. Наличие отдельных компараторов облегчает их тестирование; отдельным функциям было бы труднее оправдать обнародование.

Я нашел одну ошибку, посмотрев код: для c.compare("0", "0") он возвращает -1, когда он должен вернуться 0. Помимо этого, это действительно сложно сказать.

+0

Отправил это спасибо. После добавления некоторых ошибок обработка нескольких слоев выше этого, где он вызывает Collections.Sort. Я обнаружил, что он выбрасывает следующую ошибку. Метод сравнения нарушает его общий контракт. – Jeremy

+0

Обнаружено, что мне не хватало нескольких разных случаев, которые приводили к ошибке. Разбив его дальше на отдельные части, я смог увидеть, в каких случаях он отсутствовал. – Jeremy

Смежные вопросы