• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Sorting values in HashMap

 
Rahul Shyam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I have to following HashMap


By making a TreeMap I can sort the Map on the basis of keys, but how should I sort the Map on the basis of values.
Thanks
 
ankur rathi
Ranch Hand
Posts: 3830
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Good question.

I don't know any particular method from API. But you can do it programatically, map has values() method, get collection of values from this method then call sort() method of Collections utility class (override compareTo() method of comparable interface if it require...) then again store data back to map.

I hope everything is right and clear.
 
Rahul Shyam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by rathi ji:
Good question.

I don't know any particular method from API. But you can do it programatically, map has values() method, get collection of values from this method then call sort() method of Collections utility class (override compareTo() method of comparable interface if it require...) then again store data back to map.

I hope everything is right and clear.


Thanks for replying.
I think that would sort the values but not change the keys position. I need to sort the Map on the basis of values. The key value pairing should remain intact.
If I use the sort method and then put the values back, I'll get

A, 12
B, 30
C, 45
D, 60
E, 71
F, 80
In this case the key value combination is distorted.
What I need is

A, 12
E, 30
F, 45
B, 60
D, 71
C, 80

Say this example is students and their marks Map. A scored 12, B scored 60..
I want to sort the students on the basis of their marks.
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My first instinct is to ask "Why do you want to do this?" I wonder if there is a better way to accomplish what you want to do. If you would like to describe the overall problem in some more detail, we will be more than willing to offer alternate solutions. One possibility is to create your own class that contains the data that you are currently using as the value and key in your Map. Either this class can implement Comparable or you can write a separate class that implements Comparator. Then you can create a List with objects of this custom class and use Collections.sort() to sort it. Without knowing the exact details of your project, I cannot tell if this is a good way to solve the problem, though. This is just an example to show that there are alternative approaches.

With that said, you can sort a Map by its values in several ways. One way uses the entrySet() method and a new Map (or maybe a List). I'll leave the details as the proverbial exercise for the reader.

Layne
 
Rahul Shyam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Layne Lund:
My first instinct is to ask "Why do you want to do this?" I wonder if there is a better way to accomplish what you want to do. If you would like to describe the overall problem in some more detail, we will be more than willing to offer alternate solutions. One possibility is to create your own class that contains the data that you are currently using as the value and key in your Map. Either this class can implement Comparable or you can write a separate class that implements Comparator. Then you can create a List with objects of this custom class and use Collections.sort() to sort it. Without knowing the exact details of your project, I cannot tell if this is a good way to solve the problem, though. This is just an example to show that there are alternative approaches.

With that said, you can sort a Map by its values in several ways. One way uses the entrySet() method and a new Map (or maybe a List). I'll leave the details as the proverbial exercise for the reader.

Layne


There is a good chance that I may be approaching the problem incorrectly.
Here is the problem


A data structure with students and their marks is given, you have to calculate the percentile of the students aaccording to this rule: the percentile of a student is the % of no of student having marks less
then him. For eg:
suppose

Student Marks
A 12
B 60
C 80
D 71
E 30
F 45


percentile of C = 5/5 *100 = 100 (out of 5 students 5
are having marks less then him)

percentile of B = 3/5*100 = 60% (out of 5, 3 have
markses less then him)

percentile of A = 0/5*100 = 0%.

I was thinking that i will create a HashMap with student names and marks. After sorting them on the basis is values, I'll have them in a ascending order of values, so I'll be able to find out who stands in which position and then calculate their percentiles.
I think I am taking a wrong approach, there must be a cleaner way to do this.
[ July 30, 2005: Message edited by: Rahul Shyam ]
 
Rick O'Shay
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
That's not a bad question. Seems reasonable to have a sorted list that also has an index: a map whose value collection is sorted. The answer is to use a Map implementation whose value collection is sorted. A simple implementation to do but not a stock component.
 
Rick O'Shay
Ranch Hand
Posts: 531
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Corollary: needless to say you can always sort the values collection independently but that's not news.
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The "Java Way" to do this:

1) Create a Mark class, which stores a student name and grade in member variables
2) Write another class GradeComparator that implements Comparator, and compares two Mark objects based on grades
3) From the daata, create a bunch of Mark objects, and put them in a List
4) Sort the List using the GradeComparator.

There's no Map involved.
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:
The "Java Way" to do this:

1) Create a Mark class, which stores a student name and grade in member variables
2) Write another class GradeComparator that implements Comparator, and compares two Mark objects based on grades
3) From the daata, create a bunch of Mark objects, and put them in a List
4) Sort the List using the GradeComparator.

There's no Map involved.


I agree with EFH here. In fact, this is essentially the alternative that I offered earlier. Also, I would suggest that you consider if you want the Mark class to implement Comparable instead of having a separate Comparator class. The main consideration here is to decided if Marks have a "natural" ordering and define what this ordering is. In this case, it seems that it would be natural to sort Marks by the score and not the name. To me, this means that implementing Comparable would be more natural than creating a separate Comparator.

HTH

Layne
 
Ernest Friedman-Hill
author and iconoclast
Marshal
Pie
Posts: 24211
35
Chrome Eclipse IDE Mac OS X
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Layne Lund:
To me, this means that implementing Comparable would be more natural than creating a separate Comparator.


Unless you next want to print out a chart of students and their grades to hang on your office door! It could go either way, really. I tend to use Comparable fairly rarely in my own work, on the assumption that there are always multiple ways to sort things.

In any case, Layne's right -- he gets credit for my solution. I'm apparently posting too quickly without reading enough today, again. I need to take a chill pill, as my daughter tells me.
 
Rahul Shyam
Greenhorn
Posts: 9
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks a lot for all your replies.
 
Layne Lund
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Ernest Friedman-Hill:


Unless you next want to print out a chart of students and their grades to hang on your office door! It could go either way, really. I tend to use Comparable fairly rarely in my own work, on the assumption that there are always multiple ways to sort things...


To me naming the class Mark emphasizes that you care about the grades which in turn implies a natural sorting order. If you are instead dealing with students, it might be more appropriate to name the class Student instead which then might have a natural sorting using the student's name. Here I can see that Comparator would definitely be useful when multiple sorting orders are needed.

Of course, in the end, this just boils down to personal preferences when it comes to design decisions. Java does not enforce either approach. I don't even program in Java professionally (yet), so my input is purely academic anyway, so take it for the 2 cents it's worth.

Layne
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic