Comparison method violates its general contract while comparing java.util.Date -


i getting error below:

caused by: javax.faces.el.evaluationexception: java.lang.illegalargumentexception: comparison method violates general contract!     @ javax.faces.component.methodbindingmethodexpressionadapter.invoke(methodbindingmethodexpressionadapter.java:101) [jboss-jsf-api_2.1_spec-2.1.28.sp1-redhat-1.jar:2.1.28.sp1-redhat-1]     @ com.sun.faces.application.actionlistenerimpl.processaction(actionlistenerimpl.java:101) [jsf-impl-2.1.28.redhat-10.jar:2.1.28.redhat-10]     @ javax.faces.component.uicommand.broadcast(uicommand.java:315) [jboss-jsf-api_2.1_spec-2.1.28.sp1-redhat-1.jar:2.1.28.sp1-redhat-1]     @ javax.faces.component.uiviewroot.broadcastevents(uiviewroot.java:786) [jboss-jsf-api_2.1_spec-2.1.28.sp1-redhat-1.jar:2.1.28.sp1-redhat-1]     @ javax.faces.component.uiviewroot.processapplication(uiviewroot.java:1251) [jboss-jsf-api_2.1_spec-2.1.28.sp1-redhat-1.jar:2.1.28.sp1-redhat-1]     @ com.sun.faces.lifecycle.invokeapplicationphase.execute(invokeapplicationphase.java:81) [jsf-impl-2.1.28.redhat-10.jar:2.1.28.redhat-10]     @ com.sun.faces.lifecycle.phase.dophase(phase.java:101) [jsf-impl-2.1.28.redhat-10.jar:2.1.28.redhat-10]     @ com.sun.faces.lifecycle.lifecycleimpl.execute(lifecycleimpl.java:118) [jsf-impl-2.1.28.redhat-10.jar:2.1.28.redhat-10]     @ javax.faces.webapp.facesservlet.service(facesservlet.java:593) [jboss-jsf-api_2.1_spec-2.1.28.sp1-redhat-1.jar:2.1.28.sp1-redhat-1]     ... 29 more caused by: java.lang.illegalargumentexception: comparison method violates general contract!     @ java.util.timsort.mergehi(timsort.java:899) [rt.jar:1.8.0_65]     @ java.util.timsort.mergeat(timsort.java:516) [rt.jar:1.8.0_65]     @ java.util.timsort.mergeforcecollapse(timsort.java:457) [rt.jar:1.8.0_65]     @ java.util.timsort.sort(timsort.java:254) [rt.jar:1.8.0_65]     @ java.util.arrays.sort(arrays.java:1512) [rt.jar:1.8.0_65]     @ java.util.arraylist.sort(arraylist.java:1454) [rt.jar:1.8.0_65]     @ java.util.collections.sort(collections.java:175) [rt.jar:1.8.0_65] 

below code compare method. vo1.getattribute() returns java.util.date object.

    @override     public int compare(datecomparablevo vo1, datecomparablevo vo2) {         if (vo1 != null && vo1.getattribute() != null && vo2 != null && vo2.getattribute() != null) {             return vo1.getattribute().compareto(vo2.getattribute());         }         return -1;     } 

is there wrong implementation of compare method?

in case of null scenario.

why below code works without issue.

package test;  import java.util.arraylist; import java.util.collections; import java.util.comparator; import java.util.date; import java.util.list;  public class testmain {      public static void main(string[] args) {         list<employee> employees = new arraylist<employee>();         employees.add(new employee(new date()));         employees.add(null);         employees.add(new employee(new date()));         employees.add(new employee(new date()));         employees.add(null);         employees.add(new employee(new date()));         employees.add(null);         system.out.println(employees.size());         collections.sort(employees, new employeecomparator());      }  }  class employee {       private date attribute;      public employee() {         // todo auto-generated constructor stub     }      public employee(date attribute) {         this.attribute = attribute;     }       public date getattribute() {         return attribute;     }      public void setattribute(date attribute) {         this.attribute = attribute;     }      @override     public string tostring() {         return "employee [attribute=" + attribute + "]";     } }  class employeecomparator implements comparator<employee>{      @override     public int compare(employee vo1, employee vo2) {         system.out.println("vo1 : " + vo1 + " vo2 : " + vo2);          if (vo1 != null && vo1.getattribute() != null && vo2 != null && vo2.getattribute() != null) {             return vo1.getattribute().compareto(vo2.getattribute());         }         return -1;     }  } 

output

7 vo1 : null vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo2 : null vo1 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo2 : null vo1 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : null vo2 : null vo1 : null vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : null vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : null vo2 : null vo1 : null vo2 : employee [attribute=fri aug 18 11:51:11 sgt 2017] vo1 : null vo2 : null 

am missing important part in understanding compare

the "contract" comparison comparison function has define total order. 1 of requirements of total order "asymmetry", means if < b, b > a. in java terms, means if compare(a,b) (or a.compareto(b)) returns result < 0, compare(b,a) (or b.compareto(a)) must return result > 0. comparison function doesn't obey rule; if x.getattribute() non-null , y.getattribute() null, compare(x,y) returns -1 , compare(y,x) returns -1. timsort notices , throws exception when spots comparison doesn't return expects.

another way @ it: have decide beforehand order want things in if there "special" values in input (except if want objects compare "equal", order doesn't matter). suppose input contains objects getattribute() null, , objects getattribute() non-null. want ones null attribute appear in output? how want them ordered? "i don't care" not option. let's want null-attribute ones come last, don't care how null-attribute objects ordered. need write comparison function that

  • an object non-null attribute < object null attribute;
  • an object null attribute > object non-null attribute;
  • two object null attributes treated equal (comparison function returns 0).

if want null ones appear first in array, < , > in first 2 points reversed. if want 2 objects null attributes ordered based on other attribute, write comparison function that, you'll still need decide ones null attribute appear relative ones non-null attribute. maybe doesn't matter 1 choose. have choose something, , have write comparison function return result based on you've chosen.

p.s.: there's no particular reason why second code snippet employee works , first 1 doesn't. comparator in second case wrong in first one. however, timsort doesn't @ every pair of elements make sure comparison meets contract (that make o(n2) algorithm). i'm not familiar details of timsort, suspect makes check when has reason compare 2 elements see if comparison (perhaps) <0 or =0, , "knows" >0 should not possible if comparison function meets contract. it's pretty cheap check result >0 if has make comparison, doubt timsort calls comparators when doesn't have to, since execution time of comparator beyond control. basic reason second example works "you got lucky".


Comments

Popular posts from this blog

Is there a better way to structure post methods in Class Based Views -

performance - Why is XCHG reg, reg a 3 micro-op instruction on modern Intel architectures? -

jquery - Responsive Navbar with Sub Navbar -