سؤال

Im trying to sort a:

Map<String,Map<String,Object>> based on a property (dispSeq) .

An example of the data is:

ProductType={BeanTag:'xxx',dispSeq=10,.....}

ChargeType={BeanTag:'yyy',dispSeq=30.1,.....}

Something={BeanTag:'zzz',dispSeq=29,.....}

so, as above I'd like to sort it based in dispSeq.

I know that the data structure is not the best to perform a sorting... but at this point, nothing i can do to change it.

I can sort the "inside" map by doing:

private void orderColumns(Map columnDetails) {

    List<Map<String, Object>> columnsValues = new ArrayList<Map<String, Object>>(
            columnDetails.values());

    Collections.sort(columnsValues, new Comparator<Map<String, Object>>() {
        public int compare(Map<String, Object> o1, Map<String, Object> o2) {

            if (Integer.parseInt(o1.get("dispSeq").toString()) == Integer
                    .parseInt(o2.get("dispSeq").toString()))
                return 0;
            return Integer.parseInt(o1.get("dispSeq").toString()) < Integer
                    .parseInt(o2.get("dispSeq").toString()) ? -1 : 1;
        }
    });

}

But this wont work since I lose the key of the main Map.

Any idea?

هل كانت مفيدة؟

المحلول

Based on my comment above these are the two ways of sorting your map.

It may look confusing at a glance, but the idea here is to get the entry set and convert it to list and sort the list using Collections.sort() method. For the outer map case I get the entry set and on compare method take the first element from the map and compare it. You could change the comparison logic the way that suits you.

I presume you have an Object of type ProductType and it has a field dispSeq which is int/Integer. So if you have multiple Objects like ProductType, ChargeType etc. you could either you instance of comparision for casting or have a an interface for all related object with a getDispSeq() method;

Hope this helps.

private static Map<String, Object> sortInnerMap(Map<String, Object> unsortedMap) {

    List<Entry<String, Object>> list = new LinkedList<Entry<String, Object>>(unsortedMap.entrySet());

    Collections.sort(list, new Comparator<Entry<String, Object>>() {
        public int compare(Entry<String, Object> o1, Entry<String, Object> o2) {
            return ((Comparable) ((ProductType) o1.getValue()).getDispSeq())
                                   .compareTo(((ProductType) o2.getValue()).getDispSeq());
        }
    });

    Map<String, Object> sortedMap = new LinkedHashMap<String, Object>();
    for(Entry<String, Object> item : list){
        sortedMap.put(item.getKey(), item.getValue());
    }
    return sortedMap;
}

private static Map<String, Map<String, Object>> sortOuterMap(
        Map<String, Map<String, Object>> unsortedMap) {

    List<Entry<String, Map<String, Object>>> list = new LinkedList<Entry<String, Map<String, Object>>>(
            unsortedMap.entrySet());

    Collections.sort(list,
            new Comparator<Entry<String, Map<String, Object>>>() {
                public int compare(Entry<String, Map<String, Object>> o1,
                        Entry<String, Map<String, Object>> o2) {
                    return ((Comparable) ((ProductType) o1.getValue()
                            .entrySet().iterator().next().getValue())
                            .getDispSeq()).compareTo(((ProductType) o2.getValue()
                            .entrySet().iterator().next().getValue())
                            .getDispSeq());
                }
            });

    Map<String, Map<String, Object>> sortedMap = new LinkedHashMap<String, Map<String, Object>>();
    for(Entry<String, Map<String, Object>> item : list){
        sortedMap.put(item.getKey(), item.getValue());
    }
    return sortedMap;
}

نصائح أخرى

Do not sort it based on the inside map. Sort the outside map with Collections.sort() and change the compare method accordingly to get the values of dispSeq from the inside map and return the values accordingly.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top