简体   繁体   中英

Sort List of Map: need to sort list of map based on two values at one go

Need to sort the list of map having string, Object entry as given below,

List<Map<String,Object>> listOfMap = new ArrayList<Map<String,Object>>();
// creating maps
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("Number", 2);
map1.put("Date1", new Date("12-OCT-2018"));// Consider any date
map1.put("Date2", new Date("02-MAY-2017"));// Consider any date

Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("Number", 5);
map2.put("Date1", new Date("12-OCT-2018"));// Consider some date
map2.put("Date2", new Date("01-JAN-2017"));// Consider some date

// ...

Map<String, Object> mapN = new HashMap<String, Object>();
mapN.put("Number", 8);
mapN.put("Date1", new Date("10-JAN-2016"));// Consider some date
mapN.put("Date2", new Date("10-MAY-2016"));// Consider some date

With this above list of Map value, I need the below output by sorting based on date1 and date 2 at one stretch itself..

My Required order of O/p for the above input data is:

Number  Date1      Date2
8       10-Jan-16  10-May-16  //mapN 
5       12-Oct-18  1-Jan-17   //map2
2       12-Oct-18  2-May-17   //map1

I'd encapsulate your map objects into a class. In fact, you may not need the map at all since I see you are using the same keys for every map (couldn't you use attributes of a class instead?).

Once you've this encapsulation, make that class implement the comparable interface, and in your compareTo method, compare using the criteria you need.

Doing this, all you need to do afterwards is using .sort() on your list.

EDIT: If you have to conserve the maps no matter what, make a class that

implements Comparator<Map<String, Object>>

where you compare your maps, and pass it as parameter to the .sort() method of the list.

This may help you:

List<Map<String,Object>> listOfMap = new ArrayList<Map<String,Object>>();
// creating maps
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("Number", 2);
map1.put("Date1", new Date("12-OCT-2018"));// Consider any date
map1.put("Date2", new Date("02-MAY-2017"));// Consider any date

Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("Number", 5);
map2.put("Date1", new Date("12-OCT-2018"));// Consider some date
map2.put("Date2", new Date("01-JAN-2017"));// Consider some date

Map<String, Object> mapN = new HashMap<String, Object>();
mapN.put("Number", 8);
mapN.put("Date1", new Date("10-JAN-2016"));// Consider some date
mapN.put("Date2", new Date("10-MAY-2016"));// Consider some date

listOfMap.add(map1);
listOfMap.add(map2);
listOfMap.add(mapN);

Collections.sort(listOfMap, new Comparator<Map<String,Object>>() {
    @Override
    public int compare(Map<String,Object> obj1, Map<String,Object> obj2 {
        Date obj1date1 = (Date) obj1.get("Date1");
        Date obj2date1 = (Date) obj2.get("Date1");
        if(obj1date1.compareTo(obj2date1)==0) {
            Date obj1date2 = (Date) obj1.get("Date2");
            Date obj2date2 = (Date) obj2.get("Date2");
            return obj1date2.compareTo(obj2date2);
        } else
            return obj1date1.compareTo(obj2date1);
    }
});

for(Map<String,Object> map : listOfMap)
    System.out.println(map.toString());

If you opt not to use an encapsulating class you could just use a lambda function to compare your entries:

List<Map<String, Object>> lst = new ArrayList<Map<String, Object>();
lst.stream().sorted((map1, map2) -> {
    // compare the values here
    return 0;
}).forEachOrdered(map -> {/* output here */});

Of course you can use the lambda if you write an encapsulating class, too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM