compareTo(obj o) help - My implementation of it sucks :D

Hey JavaGaming! :smiley:

Never before has something worked for me, until just recently. This is because of you guys, and explosively learning
my ways with games programming :stuck_out_tongue:

I’m over stuff like walking in a tilemap, which you know I have had trouble with.

So a massive thanks to you :-*

Now to my question:
I got a fingerpoint (a huge one) to how I should proporly Z-order my tiled-landscape-thing (it
s top-down, like Zelda). I’m using the comperable interface on my “entity” object to do it.
I have a feeling I might be doing it in a bad way though, since it does not always work…
Have a look:


public int compareTo(Entity o) {
        if (this.coordY > o.coordY) {
            return 1;
        } else if (this.coordY == o.coordY) {
            if (this.priority > o.priority) {
                return 1;
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    }

It’s designed to make the objects in the scene that has the biggest Y value, the first on the list (a linkedlist btw).
If they have the same Y, the priority int should count, and the one with the biggest priority should be first.

…I do have a feeling I might be doing this waaaay wrong, hence the half-funcionality…


	public int compareTo(Entity o) {
		if (coordY == o.coordY)
			return priority - o.priority;
		return coordY - o.coordY;
	}

beware, this is just a guess and maybe stupid

That looks correct to me.

Actually, this is almost correct. The problem is that if compareTo returns 0, it is assumed that the objects are equal which they are not. If you were to use your compareTo implementation in a TreeSet lots of objects would not not make it into the set, as the TreeSet thinks it already has them.

You might have better luck with this one:


	public int compareTo(Entity o) {
		if(this==o || this.equals(o)) return 0;
		int ret = (coordY == o.coordY) ? (priority - o.priority) : (coordY - o.coordY);
		return (ret==0) ? 1 : ret;
	}

Thank you very much guys :smiley: I found out that my movement was not working correctly, upon holding the key down and that was actually causing the bug.
Again, that just showed me a different bug in the compareTo method, and then we’re back :stuck_out_tongue:
Rivens code solves that :slight_smile:

Aah, of course. I forgot that caveat. It is sort of weird, though, to return 1 for something that is equivalent but not equal. Then again there’s not much else you can do. I guess in this case that sorts it to the right which is fine.

I’m not sure this quite fulfils the requirements for compareTo() either as it isn’t transitive. For x and y that have equal coords and priority, x.compareTo(y) should be opposite to y.compareTo(x), but they’ll both return 1. Whether this is an issue depends on how you use the Entity. I had an issue with this a while back, and ended up implementing the last line something like -


return (ret==0) ? hashCode() - o.hashCode() : ret;

Not sure if anyone’s got a better idea.

Incidentally, while checking the docs for the exact wording for compareTo() I noticed that it doesn’t strictly have to be consistent with equals() - guess it depends where you’re using it but seems like a bad habit to get in to!

Yes, yes, I know, the pedants are revolting! ;D

What you said here makes me think you want the list to be sorted in descending order (to re-phrase, elements at the end have low coordY and priority). Doesn’t Java sort lists in ascending order by default, so shouldn’t we reverse the implementation in Riven’s compareTo() so that it returns -1 when this.coordY > o.coordY?

Like so?


public int compareTo(Entity o) {
    if(this==o || this.equals(o)) return 0;
    int ret = (coordY == o.coordY) ? (o.priority - priority) : (o.coordY - coordY);
    return (ret==0) ? 1 : ret;
}