Sorting Java TreeMap by value not working when more than two values have the same sort-property?

Update: You cannot return 1 from ValueComparator just because you want to avoid duplicate keys to not be removed. Check the contract of Comparator.compare.

Update: You cannot return -1 from ValueComparator just because you want to avoid duplicate keys to not be removed. Check the contract of Comparator.compare. When you pass a Comparator to TreeMap you compute a ("new") place to put the entry.No (computed) key can exist more than once in a TreeMap.

If you want to sort the orginalMap by size of the value you can do as follows: public static void main(String args) throws Exception { TreeMap> originalMap = new TreeMap>(); originalMap. Put(0, new HashSet() {{ add(6); add(7); }}); originalMap. Put(1, new HashSet() {{ add(6); }}); originalMap.

Put(2, new HashSet() {{ add(9); add(8); }}); ArrayList> list = new ArrayList>(); list. AddAll(originalMap.entrySet()); Collections. Sort(list, new Comparator>(){ public int compare(Map.

Entry> o1, Map. Entry> o2) { Integer size1 = (Integer) o1.getValue().size(); Integer size2 = (Integer) o2.getValue().size(); return size2. CompareTo(size1); } }); System.out.

Println(list); }.

Thanks a ton- your solution works great :) May I still ask why my method doesn't work (I'm interested to learn). If some change in my implementation would fix it, then it would be nice to use a Map instead of List to contain the sorted result. – jjossarin Oct 6 at 11:07 I'm sorry, you cannot since the key in a TreeMap cannot exist more than once (in your case the key is the size of the value).

When you put it a new value with the same size it will remove the old value. Updated answer slightly. – dacwe Oct 6 at 11:10 Ok, but why does it work when I have two values with the same size (both of them are inserted) and doesn't work when I have three values with the same size?

– jjossarin Oct 6 at 11:11 2 Ouch, returning -1 from your Comparator to avoiding duplicate entries to be removed is not how the contract is for Comparator. Compare is specified. You just cannot do it like that!(updated answer) – dacwe Oct 6 at 12:16 2 From the api documentation: The implementor must ensure that sgn(compare(x, y)) == -sgn(compare(y, x)) for all x and y.

If you always return -1 for equal sizes then you have broken this property. – dacwe Oct 6 at 13:00.

You can have TreeMap ordered only by keys. There is no way of creating TreeMap ordered by values, because you will get StackOverflowException. Think about it.To get an element from a tree, you need to perform comparisions, but to perform comparisions, you need to get elements.

You will have to sort it in other collection or to use Tree, you will have to encapsulate the integer (from entry value) also into the entry key and define comparator using that integer taken from a key.

Your comparator logic (which I'm not sure I follow why you'd return -1 if the set sizes are equal but they keys are different) shouldn't affect what the Map itself returns when you call get(key). Are you positive you aren't inserting null values into the initial map? What does this code look like?

If the sizes of values being compared are same, then the variable "compare" would equal zero - thus the new map would think the two keys are duplicates and only insert one of them. I don't want this, I want to retain ALL key-value pairs from the original map, so I can't return 0 from the comparator. Yes, I am not inserting nulls in the initial map.

– jjossarin Oct 6 at 10:59 Here's how the code looks like: ideone. Com/iFD9c (added this to question too). – jjossarin Oct 6 at 11:58 That is going to lead to an unstable sort then, if you return -1 when A and B have the same size, and also -1 when B and A have the same size.

I would rethink using a Comparator to do this sort of thing. – matt be Oct 6 at 12:45 how'd you suggest me to do this then? – jjossarin Oct 6 at 12:50 using dacwe's method is fine – matt be Oct 6 at 12:54.

Your comparator doesn't respect the Comparator contract: if compare(o1, o2) 0. You must find a deterministic way of comparing your elements when both sizes are the same and the integers are not identical. You could perhaps use the System.

IdentityHashCode() of the integers to compare them in this case. That said, I really wonder what you could do with such a map: you can't create new Integers and use them to get a value out of the map, and you can't modify the sets that it holds. Side note: your comparator code sample uses map and data to refer to the same map.

I thought this is handling the case: "when both sizes are the same and the integers are not identical": if (compare == 0 && o1! =o2){ return -1; } Yes, I'm aware of the drawbacks of this method and I will find better alternatives for my problems later. But I started with this, and would love to learn why this happens.

Thanks, edited to correct the mistake (data and map). – jjossarin Oct 6 at 10:54 1 You handle the case, but you handle it by breaking the contract. Re-read my answer again: you're returning -1 when comparing i1 and i2, and you're also returning -1 when returning i2 and i1.

This means that i1 is both i2. – JB Nizet Oct 6 at 13:00.

Assuming you cannot use a comparator that returns 0 with a Set, this might work: Add all the elements in originalMap.entrySet() to an ArrayList and then sort the ArrayList using your ValueComparer, changing it to return 0 as necessary. Then add all the entries in the sorted ArrayList to a LinkedHashMap.

Update: You cannot return -1 from ValueComparator just because you want to avoid duplicate keys to not be removed. Check the contract of Comparator. Compare .

Your comparator logic (which I'm not sure I follow why you'd return -1 if the set sizes are equal but they keys are different) shouldn't affect what the Map itself returns when you call get(key).

I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.

Related Questions