简体   繁体   中英

Java: Sorting a List<Map<String, Object>> dataList = new ArrayList<Map<String, Object>>(dataMap.values())

I would like to ask how to sort this list of Map by it's values which is the Object itself

This is a code from my ServiceImpl :

List<Map<String, Object>> dataList = serviceRequestDataDao.findServiceRequestData(serviceRequestQuery);

...

 Map<Long, Map<String, Object>> dataMap = toMap(dataList,customReportSetting.getReportType()); 

...

dataList = new ArrayList<Map<String,Object>>(dataMap.values());

The dataMap.values() are all the values that I have retrieved from the database. I tried to display it using this code since I want it to be sorted by Creation Date Value (from oldest to latest ):

for (Map<String, Object> mapList : dataList){
    for (Map.Entry<String, Object> entry : mapList.entrySet()){
        String key = entry.getKey();
        Object value = entry.getValue();

        if (key.equals("Creation Date")){
            System.out.println(value);
        }
    }       
}

I just don't know how to sort the WHOLE list containing map of string (keys) and objects (values) .

The output of Creation Date is like this:

05/17/2016 02:56:40 PM

遵循@Andreas 的假设,即Creation DateTimestamp

dataList.sort(Comparator.comparing(m -> (Timestamp)m.get("Creation Date")));

To sort a List of objects that don't have a natural order ( Map doesn't), you call Collections.sort(List<T> list, Comparator<? super T> c) .

Assuming your Creation Date value is a java.sql.Timestamp , this is how:

Collections.sort(dataList, new Comparator<Map<String, Object>>() {
    @Override
    public int compare(Map<String, Object> row1, Map<String, Object> row2) {
        Timestamp createDate1 = (Timestamp) row1.get("Creation Date");
        Timestamp createDate2 = (Timestamp) row2.get("Creation Date");
        return createDate1.compareTo(createDate2);
    }
});

Or this shorter lambda version if you're on Java 8+:

Collections.sort(dataList, (row1, row2) -> {
    Timestamp createDate1 = (Timestamp) row1.get("Creation Date");
    Timestamp createDate2 = (Timestamp) row2.get("Creation Date");
    return createDate1.compareTo(createDate2);
});

Which of course can be shortened to one of these two (second taken from answer by @shmosel ):

Collections.sort(dataList, (r1,r2) -> ((Timestamp)r1.get("Creation Date")).compareTo((Timestamp)r2.get("Creation Date")));

dataList.sort(Comparator.comparing(r -> (Timestamp)r.get("Creation Date")));

UPDATE

To add a secondary sort by Resolved Date , you'd first have to decide how null values sort. That was not a consideration for Creation Date , since that is a NOT NULL column, but Resolved Date is likely null capable. Let's sort null values last .

For pre-Java 8, do this:

Timestamp date1 = (Timestamp) row1.get("Creation Date");
Timestamp date2 = (Timestamp) row2.get("Creation Date");
int cmp = date1.compareTo(date2);
if (cmp == 0) {
    date1 = (Timestamp) row1.get("Resolved Date");
    date2 = (Timestamp) row2.get("Resolved Date");
    cmp = (date1 == null ? (date2 == null ? 0 : 1)
                         : (date2 == null ? -1 : date1.compareTo(date2)));
}
return cmp;

To sort null values first, swap 1 and -1 .

For Java 8, do this:

dataList.sort(Comparator.comparing((Map<String, Object> r) -> (Timestamp)r.get("Creation Date"))
                        .thenComparing(r -> (Timestamp)r.get("Resolved Date"),
                                       Comparator.nullsLast(Comparator.naturalOrder())));

With method chaining, the compiler was unable to infer the type of the r parameter, so it has to be explicitly given on the first lambda.

If I talk about list object which is given by you :

List<Map<String, Object>> dataList = serviceRequestDataDao.findServiceRequestData(serviceRequestQuery);

We can sort it by using Java 8 feature stream API :

dataList= dataList.stream().sorted(Comparator.comparing(map -> (Timestamp)map.get("Creation Date"))).collect(Collectors.toList());

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