-
Sorting HashMap based on its Values (11 messages)
- Posted by: Mayank Bhargava
- Posted on: October 21 2004 05:01 EDT
Hi,
Can someone suggest me or send a code snippet to sort the HashMap based on its values(not the keys), so that when I display, I get the values in some sorted manner.
Thanks & Regards,
VishalThreaded Messages (11)
- Sorting HashMap based on its Values by Artem Yegorov on October 21 2004 12:22 EDT
- Close, but throws out ties by Tim Ringwood on March 31 2005 10:23 EST
-
How about without LinkedHashMap by M J on October 03 2005 02:01 EDT
-
Use TreeMap by Tray Alford on October 14 2005 10:58 EDT
-
Solution - Use a List by Oluwafemi Adetula on December 14 2005 06:42 EST
-
Correction by Oluwafemi Adetula on December 15 2005 12:12 EST
-
Possible Enhancement by Alex Hill on March 16 2006 09:36 EST
- And Another Thing by Alex Hill on March 16 2006 09:38 EST
-
Possible Enhancement by Alex Hill on March 16 2006 09:36 EST
-
Correction by Oluwafemi Adetula on December 15 2005 12:12 EST
-
Solution - Use a List by Oluwafemi Adetula on December 14 2005 06:42 EST
-
Use TreeMap by Tray Alford on October 14 2005 10:58 EDT
- How to count redundant values of HashMap entrysets? by Hui Yang on July 13 2010 05:39 EDT
-
How about without LinkedHashMap by M J on October 03 2005 02:01 EDT
- Close, but throws out ties by Tim Ringwood on March 31 2005 10:23 EST
- Re: Sorting Maps based on its values by Anders Eriksson on October 24 2004 18:27 EDT
- Re: Sorting Maps based on its values by Vishal Revankar on October 25 2004 06:03 EDT
-
Sorting HashMap based on its Values[ Go to top ]
- Posted by: Artem Yegorov
- Posted on: October 21 2004 12:22 EDT
- in response to Mayank Bhargava
Something like this, maybe?
Map someMap= new LinkedHashMap();
someMap.put("key1","c");
someMap.put("key2","a");
someMap.put("key3","b");
List mapKeys = new ArrayList(someMap.keySet());
List mapValues = new ArrayList(someMap.values());
someMap.clear();
TreeSet sortedSet = new TreeSet(mapValues);
Object[] sortedArray = sortedSet.toArray();
int size = sortedArray.length;
//a) Ascending sort
for (int i=0; i<size; i++)
{
//System.out.println(sortedArray[i]);
someMap.put(mapKeys.get(mapValues.indexOf(sortedArray[i])), sortedArray[i]);
}
System.out.println(someMap);
someMap.clear();
//b) Descending sort
for (int i=size; i>0;)
{
someMap.put(mapKeys.get(mapValues.indexOf(sortedArray[--i])), sortedArray[i]);
}
System.out.println(someMap);
Regards,
Artem D. Yegorov
http://www.activexml.org -
Close, but throws out ties[ Go to top ]
- Posted by: Tim Ringwood
- Posted on: March 31 2005 10:23 EST
- in response to Artem Yegorov
That works if all the values are unique, which isn't true in my case. I ened up with the below. Maybe somebody can make it better, but it does deal with duplicate values.
public LinkedHashMap sortHashMapByValues(HashMap passedMap, boolean ascending) {
List mapKeys = new ArrayList(passedMap.keySet());
List mapValues = new ArrayList(passedMap.values());
Collections.sort(mapValues);
Collections.sort(mapKeys);
if (!ascending)
Collections.reverse(mapValues);
LinkedHashMap someMap = new LinkedHashMap();
Iterator valueIt = mapValues.iterator();
while (valueIt.hasNext()) {
Object val = valueIt.next();
Iterator keyIt = mapKeys.iterator();
while (keyIt.hasNext()) {
Object key = keyIt.next();
if (passedMap.get(key).toString().equals(val.toString())) {
passedMap.remove(key);
mapKeys.remove(key);
someMap.put(key, val);
break;
}
}
}
return someMap;
} -
How about without LinkedHashMap[ Go to top ]
- Posted by: M J
- Posted on: October 03 2005 14:01 EDT
- in response to Tim Ringwood
Any ideas on how to do this without using a LinkedHashMap? We're still on 1.3 which doesn't support LinkedHashMap and I'm not going to get the web admins to upgrade us anytime soon. -
Use TreeMap[ Go to top ]
- Posted by: Tray Alford
- Posted on: October 14 2005 10:58 EDT
- in response to M J
I would look at the TreeMap that is available in 1.3 and look at implementing the comparable interfaces to the value objects or provide a comparator object. This should take care of all your probs.
http://java.sun.com/j2se/1.3/docs/api/java/util/TreeMap.html -
Solution - Use a List[ Go to top ]
- Posted by: Oluwafemi Adetula
- Posted on: December 14 2005 18:42 EST
- in response to Tray Alford
I had the same problem - could not sort a map based on values rather than keys. To solve this I simply created a list of objects, where each object wraps a Map.Entry and implements java.lang.Comparable.
Here's the class:
-----
import java.util.*;
public class CustomEntry implements Comparable{
private Map.Entry entry;
public CustomEntry(Map.Entry entry) {
this.entry = entry;
}
public Map.Entry getEntry() {
return this.entry;
}
public int compareTo(CombinationEntry anotherEntry) {
Integer thisIntegerVal = (Integer)(this.getEntry().getValue());
int thisVal = thisIntegerVal.intValue();
Integer anotherIntegerVal = (Integer)(anotherEntry.getEntry().getValue());
int anotherVal = anotherIntegerVal.intValue();
return (thisVal<anotherVal ? 1 : (thisVal==anotherVal ? 0 : -1));
}
public int compareTo(Object o) {
return compareTo((CombinationEntry)o);
}
}
-----
You first convert your map to a list of these custom entries (here's a method, which does this):
----------
public static List convertMapToList(Map map) {
List list = new ArrayList();
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry)iterator.next();
CustomEntry customEntry = new CustomEntry(entry);
list.add(customEntry);
}
return list;
}
----------
Now you can sort the list produced from the above method by calling java.util.Collections.sort(List list).
Unfortunately, what you are left with is not a map anymore but a list pretending to be a map! -
Correction[ Go to top ]
- Posted by: Oluwafemi Adetula
- Posted on: December 15 2005 12:12 EST
- in response to Oluwafemi Adetula
In my previous post there were 2 errors - CombinationEntry should be CustomEntry. Here is the corrected version of my message:
--------
I had the same problem - could not sort a map based on values rather than keys. To solve this I simply created a list of objects, where each object wraps a Map.Entry and implements java.lang.Comparable.
Here's the class:
-----
import java.util.*;
public class CustomEntry implements Comparable{
private Map.Entry entry;
public CustomEntry(Map.Entry entry) {
this.entry = entry;
}
public Map.Entry getEntry() {
return this.entry;
}
public int compareTo(CustomEntry anotherEntry) {
Integer thisIntegerVal = (Integer)(this.getEntry().getValue());
int thisVal = thisIntegerVal.intValue();
Integer anotherIntegerVal = (Integer)(anotherEntry.getEntry().getValue());
int anotherVal = anotherIntegerVal.intValue();
return (thisVal<anotherVal ? 1 : (thisVal==anotherVal ? 0 : -1));
}
public int compareTo(Object o) {
return compareTo((CustomEntry)o);
}
}
-----
You first convert your map to a list of these custom entries (here's a method, which does this):
----------
public static List convertMapToList(Map map) {
List list = new ArrayList();
Set entrySet = map.entrySet();
Iterator iterator = entrySet.iterator();
while (iterator.hasNext()) {
Map.Entry entry = (Map.Entry)iterator.next();
CustomEntry customEntry = new CustomEntry(entry);
list.add(customEntry);
}
return list;
}
----------
Now you can sort the list produced from the above method by calling java.util.Collections.sort(List list).
Unfortunately, what you are left with is not a map anymore but a list pretending to be a map! -
Possible Enhancement[ Go to top ]
- Posted by: Alex Hill
- Posted on: March 16 2006 09:36 EST
- in response to Oluwafemi Adetula
Along the same lines as Oluwafemi's. Using an annonymous inner class is a little cleaner perhaps.
----------------------------
Map<String, Integer> map = new HashMap<String, Integer>();
// --- Put entries into map here ---
// Get a list of the entries in the map
List<Map.Entry<String, Integer>> list = new Vector<Map.Entry<String, Integer>>(map.entrySet());
// Sort the list using an annonymous inner class implementing Comparator for the compare method
java.util.Collections.sort(list, new Comparator<Map.Entry<String, Integer>>(){
public int compare(Map.Entry<String, Integer> entry, Map.Entry<String, Integer> entry1)
{
// Return 0 for a match, -1 for less than and +1 for more then
return (entry.getValue().equals(entry1.getValue()) ? 0 : (entry.getValue() > entry1.getValue() ? 1 : -1));
}
});
// Clear the map
map.clear();
// Copy back the entries now in order
for (Map.Entry<String, Integer> entry: list)
{
map.put(entry.getKey(), entry.getValue());
} -
And Another Thing[ Go to top ]
- Posted by: Alex Hill
- Posted on: March 16 2006 09:38 EST
- in response to Alex Hill
Not sure that it's good practise to consider a Map as having an ordering at all. -
How to count redundant values of HashMap entrysets?[ Go to top ]
- Posted by: Hui Yang
- Posted on: July 13 2010 17:39 EDT
- in response to Tim Ringwood
How can I count this hashmap? I would like to display:
1. All champions who won more than once - show the number that they won. eg. Uraguay: 2
2. I would like to display the country who won most World Cup: say Brazil: 5
The above should be all related to counting utility. Can someone help? Thx much.import java.util.Map;
import java.util.HashMap;public class FIFAFinalMap {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
// add world cup year and champions
map.put("1930", "Uruguay");
map.put("1934", "Italy");
map.put("1938", "Italy");
map.put("1950", "Uruguay");
map.put("1954", "West Germany");
map.put("1958", "Brazil");
map.put("1962", "Brazil");
map.put("1966", "England");
map.put("1970", "Brazil");
map.put("1974", "West Germany");
map.put("1978", "Argentina");
map.put("1982", "Italy");
map.put("1986", "Argentina");
map.put("1990", "West Germany");
map.put("1994", "Brazil");
map.put("1998", "France");
map.put("2002", "Brazil");
map.put("2006", "Italy");
map.put("2010", "Spain");// display map
System.out.println(map);// for loop the map
for (Map.Entry<String, String> me : map.entrySet()) {
String year = me.getKey();
String champion = me.getValue();
System.out.println(year + ": " + champion);
}System.out.println("\nShall we bow to octopus Paul? :)");
// sort by year and count???
}
} -
Re: Sorting Maps based on its values[ Go to top ]
- Posted by: Anders Eriksson
- Posted on: October 24 2004 18:27 EDT
- in response to Mayank Bhargava
If it doesn't have to be a 'Hash' map and if you're allowed to leverage some nice open source you may want to consider automaticly sorted maps like the TreeBidiMap (a SortedBidiMap) of Jakarta Commons Collections. Direct link to Javadoc
http://jakarta.apache.org/commons/collections/apidocs-COLLECTIONS_3_1/org/apache/commons/collections/bidimap/TreeBidiMap.html -
Re: Sorting Maps based on its values[ Go to top ]
- Posted by: Vishal Revankar
- Posted on: October 25 2004 06:03 EDT
- in response to Anders Eriksson
Thank You, Artem & Anders, That was of great help.
Regards,
Vishal