Java 如何使用Comparator按键和值对HashMap进行排序(粘贴所有代码,帖子会很长)

Java 如何使用Comparator按键和值对HashMap进行排序(粘贴所有代码,帖子会很长),java,Java,从零开始,让人们的眼睛不流血,以下是我最近的进展: Set<Entry<GregorianCalendar, Event>> map = (MyCalendarTester.myCal.getMyCalHash().entrySet()); LinkedList<Map.Entry<GregorianCalendar, Event>> list = new LinkedList<Map.Entry<Gr

从零开始,让人们的眼睛不流血,以下是我最近的进展:

        Set<Entry<GregorianCalendar, Event>> map = (MyCalendarTester.myCal.getMyCalHash().entrySet());

        LinkedList<Map.Entry<GregorianCalendar, Event>> list = new LinkedList<Map.Entry<GregorianCalendar,Event>>(map); 
          Collections.sort(list, new Comparator<Map.Entry<GregorianCalendar, Event>>() {
                public int compare(Map.Entry<GregorianCalendar, Event> e1, Map.Entry<GregorianCalendar,Event> e2) {
                    int r;
                    r = e1.getKey().compareTo(e2.getKey());
                    if (r!=0) return r;
                    r = e1.getValue().compareTo(e2.getValue());
                    return r;
                }
            });

          Iterator<Map.Entry<GregorianCalendar,Event>> i2 = list.iterator();
            while (i2.hasNext()) {

                System.out.println(i2.next() + " , ");
            }
通过创建以下日期和事件: 测试4 04/16/2016 2:23,5:56

测试5 03/15/2015 1:11

测试6 08/29/2017 7:51,23:59

测试7 04/16/2016 1:23,5:56

我的程序产生:

java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=“America/Los_Angeles”,偏移量=-2880000,DSTSCAVEN=3600000,useDaylight=true,过渡期=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-2880000,dstSaves=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDayOfWeek=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],周的第一天=1,周的第一天=1,纪元=1,年=2015,月=3,年的第周=12,月的第周=3,月的第日=15,年的第日=75,周的第日=2,周的第日=3,上午下午=0,小时=9,日的小时=9,分钟=30,秒=38,毫秒=260,分区偏移量=-2880000,DST偏移量=3600000]=Event@791d9ad , java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=“America/Los_Angeles”,偏移量=-2880000,DSTSCAVEN=3600000,useDaylight=true,过渡期=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-2880000,dstSaves=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDayOfWeek=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],周的第一天=1,周的第一天=1,纪元=1,年=2016,月=4,年的第周=12,月的第周=3,月的第日=16,年的第日=75,周的第日=2,周的第日=3,上午下午=0,小时=9,日的小时=9,分钟=30,秒=38,毫秒=260,分区偏移量=-2880000,DST偏移量=3600000]=Event@7869f0bc , java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id=“America/Los_Angeles”,偏移量=-2880000,DSTSCAVEN=3600000,useDaylight=true,过渡期=185,lastRule=java.util.SimpleTimeZone[id=America/Los_Angeles,offset=-2880000,dstSaves=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDayOfWeek=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],周的第一天=1,周的第一天=1,纪元=1,年=2017,月=8,年的第周=12,月的第周=3,月的第日=29,年的第日=75,周的第日=2,周的第日=3,上午下午=0,小时=9,日的小时=9,分钟=30,秒=38,毫秒=462,分区偏移量=-288000000,DST偏移量=3600000]=Event@733c0466,

(抱歉,不知道如何很好地格式化该文件) 问题是(1)除了月的第_天之外,它们都是相同的,(2)它吃掉了重复的一天,然后(3)我不确定如何使用LinkedList从日历中提取我需要的相关信息(基本上是如何格式化的)


再次抱歉,这花费了这么长时间,但这超出了我自己的编程能力。

使用
TreeMap
,它是按键排序的。您不能同时拥有两个世界的最佳功能(O(1)访问时间和排序键)。显然有一些方法可以按排序方式进行迭代,但这些方法依赖于将所有键复制到一个列表中,对该列表进行排序,然后按该顺序获取所有值。但实际上,如果你想要一个按键排序的图,你应该使用树形图。树形图是专门为此目的而设计的。

你可以尝试使用番石榴,它可以让你做两件事事情:(1)每个键有多个值,(2)保持键和值排序(根据自然顺序或提供的比较器):

//对于K和V的自然顺序:
TreeMultimap mMap=TreeMultimap.create();
//对于K和V的定制订购:
TreeMultimap mMap=TreeMultimap.create(
新比较器(){
整数比较(kO1,kO2){
//您在这里的实现
}
},
新比较器(){
整数比较(vO1,vO2){
//您在这里的实现
}
}
);
接下来,您可以迭代多重映射K,V对,如下所示:

for (Map.Entry<K, V> e : mMap.entries()) {
  // entries are sorted by K first and then by V
  K k = e.getKey();
  V v = e.getValue();
  // do something with k, v
}
for(Map.Entry e:mMap.entries()){
//条目先按K排序,然后按V排序
K=e.getKey();
V=e.getValue();
//用k,v做点什么
}

有关
MultiMap
的更多信息可用。

HashMaps无法排序,句号。您可以将键和/或值复制到列表中,然后进行排序?此外,没有人(包括我)希望查看您的所有代码。(这就是为什么我没有这样做,我的评论是关于标题中的问题)@immibis我知道,但每当我尝试进入某个特定部分时,我都没有收到足够好的答案,无法与我的设置配合使用。无论如何,我编辑了最相关的部分。(这也是我最近的一次尝试)还有一件事…一个映射,根据定义,每个键只包含一个值。因此,你永远不会在同一个映射中找到两个匹配的键。不。对于任何给定的键,要么它映射到一个值,要么它不在映射中。我使用了一个树集,它可以很好地对键进行排序,但现在我需要第二级排序深度来排序ort位于相同日期(键)的值.
TreeSet
是一个排序的
Set
,它是一个单个值的集合。
TreeMap
是一个排序的
MAP
,它是一个键值对的集合。您可以使用
TreeMap
使结构始终按键排序,并且同一键的值也始终按键排序d、 有趣的是,我从来没有听说过番石榴树地图。我会看看它是否有用。谢谢。如果你对番石榴一点都不熟悉,看看它,它是一个救命稻草。
// For natural ordering of both K and V:
TreeMultimap<K, V> mMap = TreeMultimap.create();

// For custom ordering of K and V:
TreeMultimap<K, V> mMap = TreeMultimap.create(
  new Comparator<K>() {
    int compare(K o1, K o2) {
      // your implementation here
    }
  },
  new Comparator<V>() {
    int compare(V o1, V o2) {
      // your implementation here
    }
  }
);
for (Map.Entry<K, V> e : mMap.entries()) {
  // entries are sorted by K first and then by V
  K k = e.getKey();
  V v = e.getValue();
  // do something with k, v
}