Reputation: 26271
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
Upvotes: 29
Views: 132760
Reputation: 2491
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()))
Upvotes: 1
Reputation: 455
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")));
Upvotes: 0
Reputation: 77
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)
}
Upvotes: 5
Reputation: 601
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) {
}
Upvotes: 0
Reputation: 4030
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.
Upvotes: 4
Reputation: 8553
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("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
}
Upvotes: 0
Reputation: 691685
The following code works perfectly
public Comparator<Map<String, String>> mapComparator = new Comparator<Map<String, String>>() {
public int compare(Map<String, String> m1, Map<String, String> m2) {
return m1.get("name").compareTo(m2.get("name"));
}
}
Collections.sort(list, mapComparator);
But your maps should probably be instances of a specific class.
Upvotes: 43
Reputation: 20096
@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"));
}
Upvotes: 7
Reputation: 1500225
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?
Upvotes: 7