简体   繁体   English

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

[英]How can I sort a map contains another map by numbers

I have a HashMap of type: 我有一个类型的HashMap:

HashMap<String, HashMap<String, Integer>>

This HashMap has values like 这个HashMap的值类似于

{name, {dateasString, numberOfTasks}} 

I want to sort this by numberOfTasks . 我想通过numberOfTasks对此进行排序。 I can't find the way to do that. 我找不到这样做的方法。

Create your custom Comparator that compares elemetns according to the sum of objects, and use Arrays.sort() or Collections.sort() after populating a list/array with the data: 创建自定义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);

Note, to improve performance you could use a caching mechanism to avoid recalculating the sum of each element every time it is being compared. 注意,为了提高性能,您可以使用缓存机制来避免每次比较时重新计算每个元素的总和。

Does the second HashMap have to be a HashMap ? 第二个HashMap必须是HashMap吗? Can you convert the second HashMap into a class specifically for this? 你能否将第二个HashMap转换为专门用于此类的类? Perhaps something like this: 也许是这样的:

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;
    }
}

Then you can say HashMap<String, TaskList> and access the number of tasks directly and sort them accordingly. 然后你可以说HashMap<String, TaskList>并直接访问任务数量并相应地对它们进行排序。 Even then I don't think HashMap is right for this. 即便如此,我也不认为HashMap是正确的。

You can't sort a HashMap , but you can get a sorted Array (or a List) of the keys. 您无法对HashMap排序,但可以获取键的排序数组(或列表)。 How you want to define your sort is up to you - just modify the comparator (or the numberOfTasks function that it calls:) 你想如何定义你的排序取决于你 - 只需修改比较器(或它调用的numberOfTasks函数:)

So something like this? 这样的事情呢?

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;
}

I doubt there is a way to do this in the Java APIs. 我怀疑在Java API中有一种方法可以做到这一点。 You will either have to do it manually by extracting the data in a separate model and sort that or redesign the model such as it will allow sorting on that field easier. 您将需要通过在单独的模型中提取数据并对其进行排序或重新设计模型来手动执行此操作,以便更容易对该字段进行排序。

You would have to convert the hashmap to an array. 您必须将hashmap转换为数组。 If it were possible to sort a hashmap it would completely defeat the purpose of using one in the first place. 如果可以对哈希映射进行排序,那么首先就会完全失去使用哈希映射的目的。

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

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

Hope that helps. 希望有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM