2

I have this compareTo code for my list:

public int compareTo(className a) 
{               
    return (this.long1 > a.long1) ? 1 : -1;
}

When I use Collections.sort(list), I get the following error: Comparison method violates its general contract!

When I change it to if (this.long1 >= a.long2), it works, but it does not sort properly. The longs are sorted in order, then out of order, then in order. Using >=, the output looks like this:

...
2000100
2000101
2000102
1000100
1000101
2000101
2000102
...

Now, duplicates do happen, and they need to be sorted correctly. It doesn't matter if the duplicates appear first or last, as long as they're properly grouped in order, like so:

...
2000100
2000101
2000101
2000102
2000102
1000100
1000101
...

How would I do this properly? Thank you.

UPDATE

The list is still being sorted out of order with all of the below suggestions. Is this because it's a List<Class> list = new ArrayList<Class>();? I can't use what I'm used to from C#: List<Class> list = new List<Class>().

Mark Buffalo
  • 766
  • 1
  • 10
  • 25

3 Answers3

9

You should return 0 when the two numbers are equal, or just use Long.compare :

public int compareTo(className a) 
{               
    return Long.compare(this.long1,a.long1);
}
Eran
  • 387,369
  • 54
  • 702
  • 768
  • 1
    I like this one. `Long.compare()`. – Mark Buffalo Oct 27 '15 at 11:51
  • I'd like to state that none of these suggestions are working, including all the information in the `duplicate` post, but since the post was marked as duplicate, there isn't much I can do. Still getting the same defect: list is sorted out of order. – Mark Buffalo Oct 27 '15 at 12:09
  • 1
    @EduardoScissaro You can still edit your question. Add relevant code, inputs and outputs. – Eran Oct 27 '15 at 12:10
  • Output is the same. Code is the same. I'm going to keep at it for a while. – Mark Buffalo Oct 27 '15 at 12:12
  • 1
    @EduardoScissaro You can show how you initialize your list, you can show the code of your class that implements `compareTo`. Perhaps there's something there that would help solve your problem. – Eran Oct 27 '15 at 12:14
  • Agreed. I thought it was an issue with `compareTo`, but it's much deeper than that. I'm going to try and solve it myself, though. – Mark Buffalo Oct 27 '15 at 12:18
  • 1
    Found the problem, which was totally my fault, somewhere else deep in the code, and it was messing with `compareTo`. While this doesn't answer the problem I was having, it is indeed correct when removing the code that shouldn't even be interacting with this in the first place. Technically, this answer is still correct... therefore, +1 and check. – Mark Buffalo Oct 27 '15 at 14:10
4
return (this.long1 > a.long1) ? 1 : -1;  

If both numbers are equal, this returns -1, not 0.

return (this.long1 >= a.long1) ? 1 : -1;  

Now 1 is equal, still not 0.
Correct:

if(this.long1 > a.long1) return 1;
if(this.long1 < a.long1) return -1;
return 0;
deviantfan
  • 11,268
  • 3
  • 32
  • 49
  • 1
    Although this is not incorrect but i would use something stackoverflow.com/a/33367246/1085186 as it uses library code and more readable. – StackFlowed Oct 27 '15 at 11:51
3

A correct solution would do this:

public int compareTo(className a) {               
    return this.long1 > a.long1 ? 1 : this.long1 < a.long1 ? -1 : 0;
}
meskobalazs
  • 15,741
  • 2
  • 40
  • 63