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
Post a Comment