0

I have a List<Map<String, String>>. One particular value of the map is a numeric entry with decimals. I wish to sort the list in descending order based on that particular value of the map.

for example:

List<Map<String, String>> foo= new ArrayList<Map<String, String>>();
Map<String, String> bar1 = new HashMap<>();
Map<String, String> bar2 = new HashMap<>();
Map<String, String> bar3 = new HashMap<>();

bar1.put("name", "abc");
bar1.put("score", "72.5");
bar1.put("sex", "male"); 
foo.add(bar1);

bar2.put("name", "pqr");
bar2.put("score", "98.7");
bar2.put("sex", "female"); 
foo.add(bar2);

bar3.put("name", "xyz");
bar3.put("score", "100.0");
bar3.put("sex", "male"); 
foo.add(bar3);
.
.
.
.

and so on

I want to sort the List<Map<String, String>> in descending order such that the map containing the score of 100.0 is on top.

I tried

Collections.sort( list, new Comparator<Map.Entry<K, V>>() {
    @Override
    public int compare(Map.Entry<K, V> o1, Map.Entry<K, V> o2) {
        return (o1.getValue()).compareTo(o2.getValue());
    }
});

but the "V" here is a string, while i need it to be sorted as a float. Any help would be appreciated.

Adrian
  • 2,984
  • 15
  • 27
cppnoob
  • 129
  • 1
  • 4
  • 12
  • Possible duplicate of [Sort a Map by values (Java)](https://stackoverflow.com/questions/109383/sort-a-mapkey-value-by-values-java) – Flown Sep 26 '17 at 10:23
  • How is this supposed to work if the value could not be parsed to a float? – Murat Karagöz Sep 26 '17 at 10:23
  • @Flown I may be wrong, but i have already tried that solution. My issue is with the typecasting of string to float or to be clear, sorting a map with one specific float value based on the that float value. – cppnoob Sep 26 '17 at 10:26

4 Answers4

3

If is not possible to create a class from that map then you can do something like:

Collections.sort(foo, (o1, o2) -> {
        return new BigDecimal(o2.get("score")).compareTo(new BigDecimal(o1.get("score")));
    });

or if you are not using java 8:

Collections.sort(foo, new Comparator<Map<String, String>>() {
            @Override
            public int compare(Map<String, String> o1, Map<String, String> o2) {
                return new BigDecimal(o2.get("score")).compareTo(new BigDecimal(o1.get("score")));
            }
        });
Adrian
  • 2,984
  • 15
  • 27
0

Why you need List Of map, you can go with List<SomeClass> and sort it as you wish, where Some class will hold you value for name sex score.

Edit: You can use convert your String in float or can take float as Someclass data type, it make your code very easy.

ankush yadav
  • 422
  • 3
  • 13
  • I have posted a very simplified version of a legacy code. I am using yml to make the keys dynamic. Rest assured, i have considered making a separate class, but for me, it is not currently possible – cppnoob Sep 26 '17 at 10:35
0

This could be a another simple solution.

Use Float to parse the string and use existing compare method of Float.

Collections.sort(foo, new Comparator<Map<String, String>>() {
            @Override
            public int compare(Map<String, String> o1, Map<String, String> o2) {
               return Float.compare(Float.parseFloat(o2.get("score")), Float.parseFloat(o1.get("score")));
            }
        });
nagendra547
  • 5,672
  • 3
  • 29
  • 43
0

to sort a list of map by values of specific key :

public static void sortMapByKey(List<Map<String, Object>> crList, final String sortKey, final boolean ascending) {
            Collections.sort(crList, new Comparator<Map<String, Object>>() {
                @Override
                public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                    Object obj1 = o1.get(sortKey);
                    Object obj2 = o2.get(sortKey);
                    if (obj1 != null && obj2 != null) {
                        if (ascending)
                            return obj1.toString().compareTo(obj2.toString());
                        else
                            return obj2.toString().compareTo(obj1.toString());
                    } else
                        return 0;
                }
            });
        }
Mahmoud Saleh
  • 33,303
  • 119
  • 337
  • 498