Reputation: 4661
I get an error in my sorting method.
Comparison method violates its general contract
This is my sorting object with sort method
public abstract class ComparablePerson extends IDValueItem implements
Comparable<ComparablePerson> {
private int score;
private String itemID,itemName;
//setters and getters
public int compareTo(ComparablePerson another) {
if (score == another.getScore())
return this.getItemName().compareToIgnoreCase(another.getItemName());
else if ((score) > another.getScore())
return 1;
else
return -1;
}
@Override
public boolean equals(Object o) {
final ComparablePerson other = (ComparablePerson) o;
if (score == other.getScore() && this.getItemName().equalsIgnoreCase(other.getItemName()))
return true;
else
return false;
}
I just call Collections.sort(ComparablePersonCollection);
What can be the cause of this?
Upvotes: 0
Views: 600
Reputation: 14863
ComparablePerson is abstract, the comparison method is probably overloaded elsewhere...
Can you post the client (which owns the collection) and the concrete classes?
This code works well:
public class ComparablePerson implements Comparable< ComparablePerson > {
public ComparablePerson( int score, String name ) {
_score = score;
_itemName = name;
}
@Override public int compareTo( ComparablePerson another ) {
int delta = _score - another._score;
if( delta != 0 ) return delta;
return _itemName.compareToIgnoreCase( another._itemName );
}
@Override public boolean equals( Object o ) {
return 0 == compareTo((ComparablePerson)o);
}
@Override public int hashCode() {
return super.hashCode();
}
private final int _score;
private final String _itemName;
public static void main( String[] args ) {
List< ComparablePerson > oSet = new LinkedList<>();
oSet.add( new ComparablePerson( 5, "x" ));
oSet.add( new ComparablePerson( 5, "y" ));
oSet.add( new ComparablePerson( 5, "z" ));
oSet.add( new ComparablePerson( 6, "x" ));
oSet.add( new ComparablePerson( 6, "y" ));
oSet.add( new ComparablePerson( 6, "z" ));
Collections.sort( oSet );
System.err.println( "Ok" );
}
}
Upvotes: 1
Reputation: 14307
The compareTo
and equals
method implementations seem to be inconsistent, the error is telling you that for the same two objects equals
gives true while compareTo
does not produce zero, which is incorrect. I suggest you invoke compareTo
from equals
to ensure consistency or otherwise define a custom Comparator<T>
.
Simply do:
public abstract class ComparablePerson extends IDValueItem implements Comparable<ComparablePerson> {
private int score;
private String itemID,itemName;
//setters and getters
public int compareTo(ComparablePerson another) {
if (score == another.getScore())
return this.getItemName().compareToIgnoreCase(another.getItemName());
else if ((score) > another.getScore())
return 1;
else
return -1;
}
@Override
public boolean equals(Object o) {
return compareTo(o) == 0;
}
}
Upvotes: 2