使用来自另一个Map的值按键对Map进行排序

时间:2014-06-02 14:18:10

标签: java sorting collections map

我知道有很多类似的问题,但我认为我的情况非常特殊,而且我还没找到一个能帮到我的正确答案,所以就这样了。

我有一个Map<Integer,List<String>>,其中Integer是type的一种分组,字符串列表是该类型的elementselement中的每个type都可以分配order值(默认情况下不会保存在列表中),因此我创建了Map<Integer, List<Integer>>其中包含type作为键,element order列表作为值。

我想按键对第一个Map进行排序,但这些键的值应该是第二个Map中相同键的List中的最小值。我试图通过将Collections.sort()与自定义比较器一起使用来实现此目的,但我对如何实现这一点感到有点迷茫。这是未完成的比较器代码:

 private class sortComparator implements Comparator {

    private Map<Integer, List<String>> grouped = null;
    private Map<Integer, List<Integer>> sortOrder = null;

    public sortComparator(Map<Integer, List<String>> grouped, Map<Integer, List<Integer>> sortOrder){
        this.grouped = grouped;
        this.sortOrder = sortOrder;
    }

    @Override
    public int compare(Object o1, Object o2) {

        return 0;
    }
    //get the lowest value from the values connected to a key
    private Integer sortGroups(Map<Integer,List<Integer>> sortOrder, Integer key){
        List<Integer> calcTypeOrder = sortOrder.get(key);
        Iterator orderIterator = calcTypeOrder.iterator();
        Integer firstElement;

        Collections.sort(calcTypeOrder);
        if (orderIterator.hasNext()){
            firstElement = (Integer)orderIterator.next();
        } else firstElement = 0;
        return firstElement;
    }
}

我很不确定如何处理或者我是否在正确的轨道上。我希望我能够解释我想要做的事情 编辑:根据要求提供更多解释:

Map<Integer, List<String>> grouped
//Map<Type, List<ElementNames>>
//consists of elements, which look like this
Map.EntrySet<13, List<Template 1, Template 2>> //1st entry
Map.EntrySet<24, List<Something, Something Else>> //2nd entry
Map.EntrySet<1, List<Example, Example, Example>> //3rd entry
Map.EntrySet<35, List<More Things>> //4th entry

这些信息并不能帮助我订购地图,但是我可以从数据库中获取ordered属性,该属性是为模板1和模板2设置的(在当前情况下)。所以我用这些条目制作另一张地图:

Map<Integer, List<Integer>> sorted
//Map<Type, List<ElementOrder>>
//consists of elements, which look like this
Map.EntrySet<13, List<3, 4>> //1st entry
Map.EntrySet<24, List<1, 2>> //2nd entry
Map.EntrySet<1, List<6, 7, 8>> //3rd entry
Map.EntrySet<35, List<5>> //4th entry 

所以基本上我希望第一张地图中的顺序基于第二张地图中的值。在当前情况下,第二个EntrySet值的最小值为1,第一个EntrySet值的最小值为3,这意味着在第一个Map中,它们必须切换位置。以下是它应该如何看待排序。 请记住,在开始排序之前,我已经获得了包含所有条目的映射,并且它们的键/值对相等,因为它们引用了数据库中条目的属性。

Map<Integer, List<String>> groupedAfterSort
//Map<Type, List<ElementNames>>
//consists of elements, which look like this
Map.EntrySet<24, List<Something, Something Else>> //1st entry
Map.EntrySet<13, List<Template 1, Template 2>> //2nd entry
Map.EntrySet<35, List<More Things>> //3rd entry
Map.EntrySet<1, List<Example, Example, Example>> //4th entry

1 个答案:

答案 0 :(得分:3)

这应该很简单。只需创建一个自定义比较器并参考排序顺序列表。例如,sortMap方法可以满足您的需求。

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;


public class MapSorter2 {

    public static void main(String[] args) {
        Map<Integer, List<String>> grouped = new HashMap<Integer, List<String>>();
        grouped.put(13, new ArrayList<String>() {{ add("Template 1"); add("Template 2"); }});
        grouped.put(24, new ArrayList<String>() {{ add("Something"); add("Something Else"); }});
        grouped.put(1, new ArrayList<String>() {{ add("Example"); add("Example"); add("Example"); }});
        grouped.put(35, new ArrayList<String>() {{ add("More Things"); }});

        Map<Integer, List<Integer>> sorted = new HashMap<Integer, List<Integer>>();
        sorted.put(13, new ArrayList<Integer>() {{ add(3); add(4); }});
        sorted.put(24, new ArrayList<Integer>() {{ add(1); add(2); }});
        sorted.put(1, new ArrayList<Integer>() {{ add(6); add(7); add(8); }});
        sorted.put(35, new ArrayList<Integer>() {{ add(5); }});

        Map<Integer, List<String>> sortedGrouped = sortMap(grouped, sorted);
        System.out.println(sortedGrouped);
    }

    private static Map<Integer, List<String>> sortMap(
            Map<Integer, List<String>> unsortedMap, Map<Integer, List<Integer>> sortOrder) {

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

        Collections.sort(list,
                new Comparator<Entry<Integer, List<String>>>() {

                    @Override
                    public int compare(Entry<Integer, List<String>> o1,
                            Entry<Integer, List<String>> o2) {
                        Integer key1 = o1.getKey();
                        Integer key2 = o2.getKey();
                        Integer sortObj1 = sortOrder.get(key1).get(0);
                        Integer sortObj2 = sortOrder.get(key2).get(0);
                        return sortObj1.compareTo(sortObj2);
                    }
                });

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

}