[java] sorting a List of Map<String, String>

I have a list variable created like this:

List<Map<String, String>> list = new ArrayList<Map<String, String>>();

In my Android application, this list gets populated.

just an example:

Map<String, String> map1 = new HashMap<String, String>();
map.put("name", "Josh");
...

Map<String, String> map2 = new HashMap<String, String>();
map.put("name", "Anna");
...

Map<String, String> map3 = new HashMap<String, String>();
map.put("name", "Bernie");
...

list.add(map1);
list.add(map2);
list.add(map3);

I am using list to show results in a ListView by extending BaseAdapter and implementing the various methods.

My problem: I need to sort list in alphabetical order based on the map's key name

Question: What is a simple way to sort list in alphabetical order based on the map's key name?

I can't seem to wrap my head around this. I have extracted each name from each Map into a String array, and sorted it(Arrays.sort(strArray);). But that doesn't preserve the other data in each Map, so i'm not too sure how i can preserve the other mapped values

This question is related to java android sorting

The answer is


Not really an answer to your question but I had a requirement to sort a List of maps by its values' properties, this will work in your case too:

List<Map<String, Object>> sortedListOfMaps = someListOfMaps.sorted(Comparator.comparing(map -> ((String) map.get("someKey")))).collect(Collectors.toList()))

Bit out of topic
this is a little util for watching sharedpreferences
based on upper answers
may be for someone this will be helpful

@SuppressWarnings("unused")
public void printAll() {
    Map<String, ?> prefAll = PreferenceManager
        .getDefaultSharedPreferences(context).getAll();
    if (prefAll == null) {
        return;
    }
    List<Map.Entry<String, ?>> list = new ArrayList<>();
    list.addAll(prefAll.entrySet());
    Collections.sort(list, new Comparator<Map.Entry<String, ?>>() {
        public int compare(final Map.Entry<String, ?> entry1, final Map.Entry<String, ?> entry2) {
            return entry1.getKey().compareTo(entry2.getKey());
        }
    });
    Timber.i("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
    Timber.i("Printing all sharedPreferences");
    for(Map.Entry<String, ?> entry : list) {
        Timber.i("%s: %s", entry.getKey(), entry.getValue());
    }
    Timber.i("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}

@Test
public void testSortedMaps() {
    Map<String, String> map1 = new HashMap<String, String>();
    map1.put("name", "Josh");

    Map<String, String> map2 = new HashMap<String, String>();
    map2.put("name", "Anna");

    Map<String, String> map3 = new HashMap<String, String>();
    map3.put("name", "Bernie");

    List<Map<String, String>> mapList = new ArrayList<Map<String, String>>();
    mapList.add(map1);
    mapList.add(map2);
    mapList.add(map3);

    Collections.sort(mapList, new Comparator<Map<String, String>>() {
        public int compare(final Map<String, String> o1, final Map<String, String> o2) {
            return o1.get("name").compareTo(o2.get("name"));
        }
    });

    Assert.assertEquals("Anna", mapList.get(0).get("name"));
    Assert.assertEquals("Bernie", mapList.get(1).get("name"));
    Assert.assertEquals("Josh", mapList.get(2).get("name"));

}

try {
        java.util.Collections.sort(data,
                new Comparator<Map<String, String>>() {
                    SimpleDateFormat sdf = new SimpleDateFormat(
                            "MM/dd/yyyy");

                    public int compare(final Map<String, String> map1,
                            final Map<String, String> map2) {
                        Date date1 = null, date2 = null;
                        try {
                            date1 = sdf.parse(map1.get("Date"));
                            date2 = sdf.parse(map2.get("Date"));
                        } catch (ParseException e) {
                            e.printStackTrace();
                        }
                        if (date1.compareTo(date2) > 0) {
                            return +1;
                        } else if (date1.compareTo(date2) == 0) {
                            return 0;
                        } else {
                            return -1;
                        }
                    }
                });

    } catch (Exception e) {

    }


You should implement a Comparator<Map<String, String>> which basically extracts the "name" value from the two maps it's passed, and compares them.

Then use Collections.sort(list, comparator).

Are you sure a Map<String, String> is really the best element type for your list though? Perhaps you should have another class which contains a Map<String, String> but also has a getName() method?


There are many ways to solve the same. One of the easiest ways to solve using Java 8 is given below :

As per your requirement, To sort in alphabetical order based on the map's key name

1st way :

list = list.stream()
           .sorted((a,b)-> (a.get("name")).compareTo(b.get("name")))
           .collect(Collectors.toList());

Or,

list = list.stream()
           .sorted(Comparator.comparing(map->map.get("name")))
           .collect(Collectors.toList());

2nd way :

Collections.sort(list, Comparator.comparing(map -> map.get("name")));

3rd way :

list.sort(Comparator.comparing(map-> map.get("name")));

You need to create a comparator. I am not sure why each value needs its own map but here is what the comparator would look like:

class ListMapComparator implements Comparator {
    public int compare(Object obj1, Object obj2) {
         Map<String, String> test1 = (Map<String, String>) obj1;
         Map<String, String> test2 = (Map<String, String>) obj2;
         return test1.get("name").compareTo(test2.get("name"));
    }
}

You can see it working with your above example with this:

public class MapSort {
    public List<Map<String, String>> testMap() {
         List<Map<String, String>> list = new ArrayList<Map<String, String>>();
         Map<String, String> myMap1 = new HashMap<String, String>();
         myMap1.put("name", "Josh");
         Map<String, String> myMap2 = new HashMap<String, String>();
         myMap2.put("name", "Anna");

         Map<String, String> myMap3 = new HashMap<String, String>();
         myMap3.put("name", "Bernie");


         list.add(myMap1);
         list.add(myMap2);
         list.add(myMap3);

         return list;
    }

    public static void main(String[] args) {
         MapSort ms = new MapSort();
         List<Map<String, String>> testMap = ms.testMap();
         System.out.println("Before Sort: " + testMap);
         Collections.sort(testMap, new ListMapComparator());
         System.out.println("After Sort: " + testMap);
    }
}

You will have some type safe warnings because I did not worry about these. Hope that helps.


if you want to make use of lamdas and make it a bit easier to read

  List<Map<String,String>> results;

  Comparator<Map<String,String>> sortByName = Comparator.comparing(x -> x.get("Name"));

  public void doSomething(){
    results.sort(sortByName)
  }

Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to android

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How to implement a simple scenario the OO way My eclipse won't open, i download the bundle pack it keeps saying error log getting " (1) no such column: _id10 " error java doesn't run if structure inside of onclick listener Cannot retrieve string(s) from preferences (settings) strange error in my Animation Drawable how to put image in a bundle and pass it to another activity FragmentActivity to Fragment A failure occurred while executing com.android.build.gradle.internal.tasks

Examples related to sorting

Sort Array of object by object field in Angular 6 Sorting a list with stream.sorted() in Java How to sort dates from Oldest to Newest in Excel? how to sort pandas dataframe from one column Reverse a comparator in Java 8 Find the unique values in a column and then sort them pandas groupby sort within groups pandas groupby sort descending order Efficiently sorting a numpy array in descending order? Swift: Sort array of objects alphabetically