如何按键然后按值对HashMap进行排序?

时间:2015-03-15 23:30:18

标签: java

我有以下HashMap

HashMap<GregorianCalendar, Event> calHash new HashMap<GregorianCalendar, Event>();

我能够通过键对它进行排序:

SortedSet<GregorianCalendar> keys = new TreeSet<GregorianCalendar>(calHash.keySet());

我还使我的Event类实现了Comparable并覆盖了compareTo方法,如下所示:

@Override
    public int compareTo(Object e) {
        // TODO Auto-generated method stub
       int hour = ((Event) e).getStartTime().get(Calendar.HOUR_OF_DAY);
       int minute = ((Event) e).getStartTime().get(Calendar.MINUTE);
       int anotherHour = this.startTime.get(Calendar.HOUR_OF_DAY);
       int anotherMinute = this.startTime.get(Calendar.MINUTE);

       if(anotherHour - hour == 0 ){
           return anotherMinute - minute;
       }else{
           return anotherHour - hour;
       }


    return 0;

    }
}

通过上述内容,我可以按升序对事件(值)进行排序。现在我的问题是,如何通过键对HashMap进行排序,然后如果相同的键具有多个值(按不同时间安排的事件),则在此之后对其进行排序?

我似乎只能找到如何对这两种方式进行排序,但现在两者都是双重排序。

2 个答案:

答案 0 :(得分:3)

使用calHash.entrySet()。这将为您提供一组Map.Entry,然后您可以将其转储到new LinkedList<Map.Entry>(entrySet)

然后,您可以使用Collections.sort(list, comparator)使用自定义比较器对该列表进行排序,该比较器按一个条件对这些条目进行排序,如果该条件相同,则按其他条件进行排序。

这是一个匿名比较器的例子:

Collections.sort(list, new Comparator<Map.Entry>() {
    public int compare(Map.Entry e1, Map.Entry e2) {
       // do comparisons here
       return 0;    
    }
});

答案 1 :(得分:1)

地图不能有多个具有相同键的条目,因此需要更多的工作来按键排序,然后按值排序。

也许最简单的方法是创建一个新的Map<GregorianCalendar, List<Event>>,其中Map中的每个条目都将一个键映射到一个事件列表。

如果同时有多个事件,则将事件添加到列表中。

然后,您可以使用Collections.sort()对列表进行排序。

顺便说一句,您可以使用TreeMap创建一个有序地图,而不是创建一个Hashmap,然后只为密钥创建一个单独的SortedSet。

Map<GregorianCalendar, List<Event>> map = new TreeMap<>();