wood burning stoves 2.0*
The moose likes Java in General and the fly likes Sorting values in a map Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "Sorting values in a map" Watch "Sorting values in a map" New topic
Author

Sorting values in a map

F Merchant
Greenhorn

Joined: Oct 02, 2012
Posts: 11
I want to sort a map in decreasing order based on the values.
However, the sorted map is being displayed as empty {}.
Is there something wrong with my logic?



Thanks!
Christophe Verré
Sheriff

Joined: Nov 24, 2005
Posts: 14687
    
  16

Setting the original map in a Comparator class will not populate the new TreeMap. The TreeMap uses your ValueComparator to compare its values, that's all. But it will remain empty. Maybe you wanted to do :


[My Blog]
All roads lead to JavaRanch
F Merchant
Greenhorn

Joined: Oct 02, 2012
Posts: 11
I tried that...solved the {} problem.
But I think my logic is wrong.
The map contains words and the frequency of their occurence.
{to=5, scs=1, basis=1, for=2, determine=1, by=1...}
Now I want to sort the map based on frequency.
But I'm getting a map with the words sorted in alphabetical order.
{a=7, ae=1, aerodynamics=1, after=1...}
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 37890
    
  22
The problem is that you are sorting on the K part of the Map.Entry, and you want to sort on the V. That is awkward. You cannot simply sort of the V, nor can you put them into a Map<Integer, String> because you will suffer duplicate Ks. You cannot simply put all the pairs into a TreeSet<Map.Entry<String, Integer>> and sort on the Integer, because you will get collisions too.
In both cases the collisions will cause entries to be lost.
It is worth seeing whether you can find a bidirectional map which serves your purposes. I don’t think there is one in the Oracle/Sun API, so try Apache Commons.
You can design your own tree set, taking the Integer as the value to sort on, and putting duplicate entries into Lists within the tree.
You can put all the entries into a List (or an array) and sort the List. If you sort the List on the Integer first, and sort it with a “stable” algorithm on the String later, you will get the Strings in ASCIIbetical order within the frequencies.
Martin Vajsar
Sheriff

Joined: Aug 22, 2010
Posts: 3606
    
  60

I'd suggest creating a class (say, Word) that would keep the word and its frequency, a comparator for this class which would compare the frequencies, creating instances of the Word class from the original map, putting these instances into a List<Word> (an ArrayList, probably) and sorting that list.

Also note that your ValueComparator class has a bug: an instance will not be equal to itself (your compare function never returns 0). Even if you somehow managed to get the scheme working (it would be possible, just very cumbersome), you wouldn't be able to retrieve values from the map using a string as a key. (I bumped into exactly this same problem very recently )
F Merchant
Greenhorn

Joined: Oct 02, 2012
Posts: 11
Oh ok....I'll try again.
Thanks!
F Merchant
Greenhorn

Joined: Oct 02, 2012
Posts: 11
I found this code: http://ideone.com/dq3Lu
But I can't understand one thing. In the compare(), we only take care of duplicate values. Where(or which statement) sorting is taking place.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

F Merchant wrote:I found this code: http://ideone.com/dq3Lu
But I can't understand one thing. In the compare(), we only take care of duplicate values. Where(or which statement) sorting is taking place.


If the values are not equal, then we already have the comparison result (negative or positive) so we just return that.

If they're equal (comparison returned 0), then we compare the keys and return that comparison result.

Note that there's no sorting code here. This is just comparison code to order any two or our objects. The sort routine will call our comparison method on various pairs of objects and reorder them or not depending on the results.
F Merchant
Greenhorn

Joined: Oct 02, 2012
Posts: 11
Understood! Thanks!!
So basically I cannot sort a map based on the value.
But for temporary ordering, something like the above code can be done.
Jeff Verdegan
Bartender

Joined: Jan 03, 2004
Posts: 6109
    
    6

F Merchant wrote:Understood! Thanks!!
So basically I cannot sort a map based on the value.


You could write your own Map implementation whose iteration order is based on the sort order of the values. Heck, there may even be one floating around at apache or sourceforge.

But for temporary ordering, something like the above code can be done.


Yes.
Winston Gutkowski
Bartender

Joined: Mar 17, 2011
Posts: 7487
    
  18

F Merchant wrote:Understood! Thanks!!
So basically I cannot sort a map based on the value.
But for temporary ordering, something like the above code can be done.

If it works, sure; but it seems to me that you're going all around the houses, when doing what Martin suggested (a Word class) would put you in position to sort a bunch of words exactly as you want. And in that case, do you really care whether it's a Map or a List ?

Hint: Implementing a Map that's dynamically sortable in lots of ways is probably overkill for what you need.

Winston

BTW: I broke up those enormous comment lines in your code. Please re-read the UseCodeTags (←click) page thoroughly. Thanks.


Isn't it funny how there's always time and money enough to do it WRONG?
Articles by Winston can be found here
F Merchant
Greenhorn

Joined: Oct 02, 2012
Posts: 11
Hmmm....ok. I'll try out the Word class. Thanks everyone!
And Winston, I'll be careful about the code tags!
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Sorting values in a map
 
Similar Threads
Reading one line from a text
Replacing a word in a text file
to read lines inside brackets
Error printing out from a read in file.
Showing Exception Message in client side