2016-04-13 2 views
-1

У меня есть проверка причины возникновения этого исключения. Не могли бы вы направить меня? Что я делаю неправильно в блоке кода ниже?Метод сравнения нарушает его общее исключение контракта

 Collections.sort(discountGroupDetailList, new Comparator<DiscountGroupDetail>() { 
      long bdsIdOne; 
      long bdsIdTwo; 

      public int compare(DiscountGroupDetail discountGroupDetailOne, DiscountGroupDetail discountGroupDetailTwo) { 
       boolean discOne; 
       boolean discTwo; 
       SimpleDateFormat DATE_FORMATER = new SimpleDateFormat("yyyy/MM/dd"); 
       int compVal = 0; 
       discOne = discountGroupDetailOne != null && discountGroupDetailOne.getServiceId() != null 
         && discountGroupDetailOne.getServiceId().getCodeAndVersion() != null 
         && discountGroupDetailOne.getServiceId().getCodeAndVersion().getCodeDetail() != null 
         && discountGroupDetailOne.getServiceId().getCodeAndVersion().getCodeDetail().getCode() != null; 

       discTwo = discountGroupDetailTwo != null && discountGroupDetailTwo.getServiceId() != null 
         && discountGroupDetailTwo.getServiceId().getCodeAndVersion() != null 
         && discountGroupDetailTwo.getServiceId().getCodeAndVersion().getCodeDetail() != null 
         && discountGroupDetailTwo.getServiceId().getCodeAndVersion().getCodeDetail().getCode() != null; 

       if (discOne == true && discTwo == true) { 
        bdsIdOne = MessageBuilderHelper.getBaseDiscountServiceById(discountGroupDetailOne.getServiceId()) 
          .getBdsIdNbr(); 

        bdsIdTwo = MessageBuilderHelper.getBaseDiscountServiceById(discountGroupDetailTwo.getServiceId()) 
          .getBdsIdNbr(); 
        compVal = (int) (bdsIdOne - bdsIdTwo); 
       } 



       DateRange dateRangeOne = discountGroupDetailOne != null ? discountGroupDetailOne.getDateSegment() : null; 
       DateRange dateRangeTwo = discountGroupDetailTwo != null ? discountGroupDetailTwo.getDateSegment() : null; 

       if (compVal == 0 && dateRangeOne != null && dateRangeTwo != null) { 

        Date date = new Date(); 
        compVal = DATE_FORMATER.format(date.parse(dateRangeOne.getStartDate())).compareTo(
          DATE_FORMATER.format(date.parse(dateRangeTwo.getStartDate()))); 
       } 

       DiscountCode discountTypeOne = (discountGroupDetailOne != null && discountGroupDetailOne 
         .getVolumeDiscountGroupDetail() != null) ? DiscountCode.getDiscount(discountGroupDetailOne 
         .getVolumeDiscountGroupDetail().getType()) : null; 
       DiscountCode discountTypeTwo = (discountGroupDetailTwo != null && discountGroupDetailTwo 
         .getVolumeDiscountGroupDetail() != null) ? DiscountCode.getDiscount(discountGroupDetailTwo 
         .getVolumeDiscountGroupDetail().getType()) : null; 

       boolean isFXG = ("FXG".equals(discountGroupDetailOne.getServiceGeography()) || (discountGroupDetailOne 
         .getServiceId() != null && "FXG".equals(discountGroupDetailOne.getServiceId().getOperatingCompany()))) 
         && ("FXG".equals(discountGroupDetailTwo.getServiceGeography()) || (discountGroupDetailTwo 
           .getServiceId() != null && "FXG".equals(discountGroupDetailTwo.getServiceId() 
           .getOperatingCompany()))); 

       if (compVal == 0 && discountTypeOne != null && discountTypeTwo != null && isFXG) { 
        compVal = ((int) (Integer.parseInt(discountTypeOne.getDiscountID()) - Integer.parseInt(discountTypeTwo 
          .getDiscountID()))); 
       } 

       return compVal; 
      } 
     }); 
    } 
+1

, пожалуйста, сообщите нам точное сообщение об ошибке, включая трассировку стека, если это возможно, и в какой строке это исключение. –

+4

Теперь я вижу, что если A имеет нулевой тип скидки, а B имеет непустой тип скидки, а C имеет другой тип нечетного дисконта, а все остальное равно, то A == B и A = = C и B! = C в соответствии с вашим компаратором. – immibis

+0

@ Daniel.Schroeder. Да –

ответ

1

Это почти всегда связано с тем, что ваш компаратор не является транзитивным или не является асимметричным. Для транзитивности, учитывая три DiscountGroupDetail объекты a, b и c, если a предшествует b и b предшествуют c, то общий контракт требует, чтобы a предшествует c во всех случаях. Аналогично, если a равно b и b равно c, тогда необходимо, чтобы a равно c. Для асимметрии, заменяя порядок сравнения для двух объектов a и b, которые не возвращаются 0, необходимо вернуть несколько противоположных знаков.

Учитывая сложную логику, мне трудно точно определить, где все идет не так, но выше, что вам нужно проверить.

+0

У меня есть список из 77 объектов в списке. Исключение срабатывает, когда он вступает в последний, если блок и возвращает comVal, как 1. в случае, если у этих двух объектов есть другой идентификатор discountID. –

+0

@shreyanshjogi - Я думаю, @immibis идентифицировал одну проблему с вашей логикой сравнения. Могут быть и другие проблемы. Когда вся логика изменяется в зависимости от того, что определенные поля имеют значение «null», легко попасть в проблему. Например, заданные 'a',' b' и 'c', если только' b' имеет определенные поля 'null', то сравнение' a' и 'b' или сравнение' b' и 'c' не будет в соответствии с сопоставлением 'a' и' c'. –

+0

Конечно, я постараюсь изменить всю логику и помнить, что сравнение между объектом должно иметь значения для сравнения –

3

@immibis заметил ответ, прежде чем смог. Чтобы обобщить принцип: скажем, вы пишете компаратор, который сравнивает несколько пар ключей. Вы хотите сравнить первую пару, а затем, если это не даст вам < или> ответ, сравните вторую пару, и если у вас все еще нет < или>, сравните третью пару и так далее.

Правило здесь заключается в том, что после сравнения первой пары вы не можете перейти ко второй паре, если только ключи в первой паре не равны , равным. В вашем случае они равны, если оба имеют «код», а коды равны, или если они оба null. Ваша ошибка в том, что вы переходите к следующей паре, если только один код равен нулю. В этом случае они не равны. Думаю, ваше мышление состоит в том, что вы не можете сравнивать коды, если один элемент не имеет кода. Но вы должны. Вам нужно указать, что элемент без кода меньше элемента с кодом (или больше, это зависит от того, как вы хотите видеть их в отсортированном массиве); и вы должны проверить это и вернуть (например) отрицательное число, если левый элемент имеет нулевой код и положительное число, если правильный элемент имеет нулевой код.

Тогда вам нужно сделать то же самое с диапазоном дат; если один аргумент имеет диапазон дат, а другой - нет, они не равны, и вы должны вернуть отрицательное или положительное число, а не перейти к третьему ключу.

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