如何按地图对包含另一个地图的地图进行排序

时间:2013-01-23 09:39:08

标签: java sorting collections hashmap

我有一个类型为:

的HashMap
HashMap<String, HashMap<String, Integer>>

此HashMap的值类似于

{name, {dateasString, numberOfTasks}} 

我希望按numberOfTasks排序。我找不到这样做的方法。

5 个答案:

答案 0 :(得分:1)

创建自定义Comparator,根据对象的总和比较elemetns,并在使用数据填充列表/数组后使用Arrays.sort()Collections.sort()

//populate example data:
final Map<String,Map<String,Integer>> map = new HashMap<String, Map<String,Integer>>();
map.put("x", new HashMap<String, Integer>());
map.get("x").put("t1",1);
map.get("x").put("t2",1);
map.get("x").put("t3",1);
map.put("y", new HashMap<String, Integer>());
map.get("y").put("t1",2);
map.get("y").put("t2",2);
map.get("y").put("t3",2);
map.put("z", new HashMap<String, Integer>());
map.get("z").put("t1",3);
map.get("z").put("t2",3);
map.get("z").put("t3",3);

//populate the data in a list:  
List<String> list = new ArrayList<String>(map.keySet());

//sort the data with a custom comparator:
Collections.sort(list, new Comparator<String>() {
    private int getSum(String s) { 
        int sum = 0;
        for (Integer x : map.get(s).values()) {
            if (x != null) sum += x;
        }
        return sum;
    }
    public int compare(String o1, String o2) {
        return new Integer(getSum(o1)).compareTo(new Integer(getSum(o2)));
    }
});

System.out.println(list);

注意,为了提高性能,您可以使用缓存机制来避免每次比较时重新计算每个元素的总和。

答案 1 :(得分:1)

第二个HashMap必须是HashMap吗?你能否将第二个HashMap转换成专门用于此类的课程?也许是这样的:

private class TaskList
{
    String dateAsString;
    int numTasks;
    public TaskList(String dateAsString, int numTasks)
    {
        this.dateAsString = dateAsString;
        this.numTasks = numTasks;
    }
    public getDateAsString()
    {
        return dateAsString;
    }
    public getNumTasks()
    {
        return numTasks;
    }
}

然后你可以说HashMap<String, TaskList>并直接访问任务数量并相应地对它们进行排序。即使这样,我也不认为HashMap是正确的。

答案 2 :(得分:1)

您无法对HashMap进行排序,但可以获取已排序的数组(或列表) 按键。您希望如何定义排序取决于您 - 只需修改 比较器(或它调用的numberOfTasks函数:)

这样的事情?

public static void main() {
    final
    HashMap<String, HashMap<String, Integer>> map = new HashMap<String, HashMap<String, Integer>>();

    String[] keys = (String[]) map.keySet().toArray();

    Arrays.sort(keys, new Comparator<String>() {
        @Override
        public int compare(String k1, String k2) {
            int v1 = numberOfTasks(map.get(k1));
            int v2 = numberOfTasks(map.get(k2));
            return Integer.valueOf(v1).compareTo(Integer.valueOf(v2));
        }
    });

    // 'keys' is now sorted the way you want.

}

public static int numberOfTasks(HashMap<String, Integer> map) {
    int max = 0;
    for (Integer i : map.values()) {
        if (i > max) max = i;
    }
    return max;
}

答案 3 :(得分:0)

我怀疑在Java API中有一种方法可以做到这一点。您将需要通过在单独的模型中提取数据并对其进行排序或重新设计模型来手动执行此操作,以便更容易对该字段进行排序。

答案 4 :(得分:0)

您必须将hashmap转换为数组。如果可以对哈希映射进行排序,那么首先就会完全失去使用哈希映射的目的。

hashMap.keySet().toArray(); // returns an array of keys
hashMap.values().toArray(); // returns an array of values

Arrays.sort(array); // sorts an array

希望有所帮助。