Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CompareTo may return 0, alternative to TreeSet/TreeMap

I need a sorted set of objects and am currently using the TreeSet. My problem is that the compareTo of the objects will often return 0, meaning the order of those two objects is to be left unchanged. TreeMap (used by TreeSet by default) will then regard them as the same object, which is not true.

What alternative to TreeMap can I use?


Use case: I have a set of displayable objects. I want to sort them by Y coordinate, so that they are rendered in the correct order. Of course, two objects may well have the same Y coordinate.

like image 279
Bart van Heukelom Avatar asked Jun 14 '10 20:06

Bart van Heukelom


2 Answers

You're defining one criteria to compare, but you need to add extra criteria.

You say:

I have a set of displayable objects. I want to sort them by Y coordinate, so that they are rendered in the correct order. Of course, two objects may well have the same Y coordinate.

So, If two elements have the same Y coordinate, what you you put first? What would be the other criteria?

It may be the creation time, it may be the x coordinate, you just have to define it:

Map<String,Thing> map = new TreeMap<String,Thing>(new Comparator<Thing>(){
     public int compare( Thing one, Thing two ) {
         int result = one.y - two.y;
         if( result == 0 ) { // same y coordinate use another criteria
             result = one.x - two.x;
             if( result == 0 ) { //still the same? Try another criteria ( maybe creation time
                 return one.creationTime - two.creationTime
             }
          }
          return result;
     }
});

You have to define when one Thing is higher / lower / equal / than other Thing . If one of the attributes is the same as other, probably you should not move them. If is there other attribute to compare the use it.

like image 108
OscarRyz Avatar answered Sep 21 '22 07:09

OscarRyz


The issue you're running into is that compareTo returning 0 means that the objects are equal. At the same time, you're putting them into a set, which does not allow multiple copies of equal elements.

Either re-write your compareTo so that unequal elements return different values, or use something like a java.util.PriorityQueue which allows multiple copies of equal elements.

like image 44
demeteloaf Avatar answered Sep 23 '22 07:09

demeteloaf