Reputation: 268
i am trying to sort a list of object that holds string and a double value:
lock.tryLock();
if (testTagRev.size() > 0)
Collections.sort(testTagRev, documentSampleComperator);
lock.unlock();
documentSampleComperator is a type documentSampleComparer:
class documentSampleComparer implements Comparator<DocumentSample> {
@Override
public int compare(DocumentSample x, DocumentSample y) {
int ans = x.getText().toString().compareTo(y.getText().toString());
// ans = utils.listToString(x.getText(), ' ').compareTo(utils.listToString(y.getText(),' ')); also didn't work
if (ans == 0)
return Integer.compare(x.hashCode(), y.hashCode());
else return ans;
}
}
even though the compactor is transitive i still get this exception :
Exception in thread "main" java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.TimSort.mergeLo(TimSort.java:747)
at java.util.TimSort.mergeAt(TimSort.java:483)
at java.util.TimSort.mergeCollapse(TimSort.java:410)
at java.util.TimSort.sort(TimSort.java:214)
at java.util.TimSort.sort(TimSort.java:173)
at java.util.Arrays.sort(Arrays.java:659)
at java.util.Collections.sort(Collections.java:217)
at Trainer.MCobjectStream.<init>(MCobjectStream.java:64)
at Trainer.filterRev.<init>(filterRev.java:64)
at Trainer.Train.main(Train.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
I am using jdk 1.7.0_45 , can you see where is the problem ?
Edit: utils.listToString turn's list of string to a string, added the lock code and comment the line that i was trying to make it work before . also i should mention that the exception only occurred sometimes but i am not using threads .
Upvotes: 1
Views: 1537
Reputation: 47176
Implementing Comparator
should not involve the hashCode
of the Objects. Usually you just compare
each attribute in order of their importance. In your example, if the text is the only thing you want to compare against then it should just be:
Collections.sort(catalog, new Comparator<DocumentSample>() {
@Override
public int compare(DocumentSample x, DocumentSample y) {
return x.getText().toString().compareTo(y.getText().toString());
}
});
By comparing the default implementation of hashCode (which returns an integer representation of the objects internal address) you are saying that two objects will be considered equal if and only if they are the same object in memory.
Upvotes: 1
Reputation: 143
Try to use inner class(without that wierd 2.line in method compare).
Collections.sort(catalog, new Comparator<DocumentSample>() {
@Override
public int compare(DocumentSample x, DocumentSample y) {
int ans = x.getText().toString().compareTo(y.getText().toString());
if (ans == 0) {
return Integer.compare(x.hashCode(), y.hashCode());
} else {
return ans;
}
}
}
);
Upvotes: 0