Reputation: 2941
I have a Map having an String as Key and an ArrayList as Value. ArrayList is basically a list of four values linked to key somehow.
My sample data is :
String : [ArrayList<String>]
"USA": ["25", "5", "20", "4"]
"India": ["15", "7", "8", "2"]
"Canada": ["29", "17", "8", "6"]
I need to sort this Map in descending order as per first value in ArrayList so it becomes like below:
"Canada": ["29", "17", "8", "6"]
"USA": ["25", "5", "20","4"]
"India": ["15", "7", "8", "2"]
I am trying below function, but its not working for ArrayList type Map value:
public class MapUtil
{
public static <K, V extends Comparable<? super V>> Map<K, V>
sortByValue( Map<K, V> map )
{
List<Map.Entry<K, V>> list =
new LinkedList<Map.Entry<K, V>>( map.entrySet() );
Collections.sort( list, new Comparator<Map.Entry<K, V>>()
{
public int compare( Map.Entry<K, V> o1, Map.Entry<K, V> o2 )
{
return (o1.getValue()).compareTo( o2.getValue() );
}
} );
Map<K, V> result = new LinkedHashMap<K, V>();
for (Map.Entry<K, V> entry : list)
{
result.put( entry.getKey(), entry.getValue() );
}
return result;
}
}
How can I modify this function to achieve what I need?
Upvotes: 1
Views: 719
Reputation: 2941
Modified the code as below to achieve my requirement.
Also had to change the Map value to ArrayList< Integer>
for efficient sorting.
public static <K, V extends Comparable<? super V>> Map<String, ArrayList<Integer>> sortByValue(Map<String, ArrayList<Integer>> map)
{
List<Map.Entry<String, ArrayList<Integer>>> list = new LinkedList<Map.Entry<String, ArrayList<Integer>>>(
map.entrySet());
Collections.sort(list,new Comparator<Map.Entry<String, ArrayList<Integer>>>()
{
public int compare(Map.Entry<String, ArrayList<Integer>> o1,Map.Entry<String, ArrayList<Integer>> o2)
{
return (o2.getValue().get(0)).compareTo(o1.getValue().get(0));
}
});
Map<String, ArrayList<Integer>> result = new LinkedHashMap<String, ArrayList<Integer>>();
for (Map.Entry<String, ArrayList<Integer>> entry : list)
{
result.put(entry.getKey(), entry.getValue());
}
return result;
}
Upvotes: 0
Reputation: 394146
You are comparing the entire ArrayList<String>
values, but you want to compare by the first value in each ArrayList
.
You should do something like :
public int compare(Map.Entry<String, ArrayList<String>> o1, Map.Entry<String, ArrayList<String>> o2)
{
return (o1.getValue().get(0)).compareTo( o2.getValue().get(0) );
}
Of course you should add null checks, in case o1.getValue() returns null or an empty list.
However, you should note that this would compare the values as Strings (in which, for example "5" > "23"), not numbers. If you want a numeric comparison, you should convert the Strings to integers, or store them as integers in the first place.
Upvotes: 3