1

我有一个 HashMap 类型:

HashMap<String, HashMap<String, Integer>>

这个 HashMap 的值如下

{name, {dateasString, numberOfTasks}} 

我想按numberOfTasks. 我找不到这样做的方法。

4

5 回答 5

1

创建Comparator根据对象总和比较元素的自定义,并在使用数据填充列表/数组之后使用Arrays.sort()or :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);

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

于 2013-01-23T09:55:28.703 回答
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这也不适合。

于 2013-01-23T09:56:57.100 回答
1

您无法对 a 进行排序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;
}
于 2013-01-23T09:57:51.513 回答
0

我怀疑在 Java API 中有没有办法做到这一点。您要么必须通过在单独的模型中提取数据并对其进行排序来手动执行此操作,要么重新设计模型,以便更轻松地在该字段上进行排序。

于 2013-01-23T09:42:55.433 回答
0

您必须将哈希图转换为数组。如果可以对哈希图进行排序,那么一开始就完全违背了使用哈希图的目的。

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

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

希望有帮助。

于 2013-01-23T09:49:57.707 回答