`
salute
  • 浏览: 55119 次
  • 性别: Icon_minigender_2
  • 来自: 上海
社区版块
存档分类
最新评论

关于HashMap排序的一点浅见

阅读更多
我们在对hashmap进行排序的时候存在一定的误解,首先在这更正下~

我在遇到这个问题的时候也上网查了相关的资料,发现大家在进行hashmap进行排序的时候存在一定的了解误区。



有很多人认为把hashmap遍历一下,然后对其中的key和value进行排序,然后打印出来~



大家想一想,这样的hashmap排序根本就不是对hashmap进行排序~最多也只能称为hashmap遍历,hashmap的遍历问题很简单,网上也有很多相关的资料,下面我给出一个例程:

   1. public static void itHashMap(Map<Object, Object> m) {
   2.   Set set = m.entrySet();
   3.   Iterator it = set.iterator();
   4.   while(it.hasNext()) {
   5.    Map.Entry<Object, Object> me = (Map.Entry<Object, Object>)it.next();
   6.    System.out.println("key:" + me.getKey() + "----value" + me.getValue());
   7.   }
   8.  }



这个方法可以将hashmap遍历,并打印出相应的key和value!



其实,单纯的hashmap是无法实现排序的,我这里的排序是指,我们将键值对按照一定的顺序put进hashmap里,然后在进行取键值对的操作的时候,在按照put进去的顺序把键值对取出来。



下面我来浅显的解释下为什么不能排序.

   1. HashMap<String, Date> hm = new HashMap<String, Date>();
   2.         hm.put("1", new Date(8,10,1));
   3.         hm.put("3", new Date(8,10,3));
   4.         hm.put("2", new Date(8,10,2));
   5.         hm.put("5", new Date(8,10,5));
   6.         hm.put("9", new Date(8,10,9));
   7.         hm.put("8", new Date(8,10,8));
   8.         hm.put("6", new Date(8,10,6));
   9.         hm.put("7", new Date(8,10,7));

我在hashmap里按照以上的顺序放入9个键值对,然后我遍历hashmap打印出上面hm里的键值对:

key:3----value:Tue Nov 03 00:00:00 CST 1908
key:5----value:Thu Nov 05 00:00:00 CST 1908
key:7----value:Sat Nov 07 00:00:00 CST 1908
key:2----value:Mon Nov 02 00:00:00 CST 1908
key:9----value:Mon Nov 09 00:00:00 CST 1908
key:8----value:Sun Nov 08 00:00:00 CST 1908
key:6----value:Fri Nov 06 00:00:00 CST 1908
key:1----value:Sun Nov 01 00:00:00 CST 1908

我们从上面的结果可以看出,取出来的顺序并我们想要的顺序!

hashmap在put的时候是根据key的hashcode进行hash然后放入对应的地方!通过Debug可以看到HashMap的存放位置,网上有很多人说是随即存放,随即取,其实不然,放的时候是根据hashcode经过 hash算法进行存放的,而我们取的时候也是想过key来取value。所以你取出来拍完序,在放入HashMap的时候哦,它又把顺序打乱了~~(这里说的打乱也不是完全没有规律可循的,主要是你根据你的key来放的)!



所以我们要实现HashMap排序的时候就要借用别的集合来完成这个功能!



基本的思路是这样的,首先遍历HashMap取出相应的键值对,然后根据key或者是value进行排序,然后放入一个有序的集合当中,这样就实现了排序!



java在JDK1.4以后提供了LinkedHashMap来帮我们实现了有序的HashMap!



LinkedHashMap取键值对的时,是按照你放入的顺序来取的!



具体的排序算法有很多种~也可以自己写个冒泡排序取排列~~



再排完序以后,我们要找到key对应的vluae或是value对应的key!找key对应的vluea的时候很简单,网上有很多资料,我这里就不说了~~关键说说找value对应的key的时候,有的朋友就不知道该怎么做了~~



下面我提供两种思路



一种是我们可以把value放入一个数组,key也放入一个数组,这样在排序的时候按照value排序的时候,我们把key的位置也交换一次,这样就保证了键值对的完整性,见例程:

   1. private static void sortHashMap(HashMap<String, Date> hm) {
   2.                        
   3.         List<Date> dateListSorted = new ArrayList<Date> ();
   4.        
   5.         int size = hm.size();
   6.         Date[] dates = new Date[size];
   7.         Set set = hm.keySet();
   8.         Iterator iteratorSet = set.iterator();
   9.         int k = 0;
  10.         while(iteratorSet.hasNext()) {
  11.             String keyStr = (String)iteratorSet.next();
  12.             System.out.println("key from set----" + keyStr);
  13.             if(keyStr!=null && !(keyStr.length()<1)) {
  14.                 dates[k] = hm.get(keyStr);
  15.                 k++;   
  16.             }
  17.             System.out.println("value from hashmap----" + hm.get(keyStr));
  18.         }
  19.         iteratorList.next());
  20.         int sizeList = dates.length;
  21.         Object[] keyObj = set.toArray();
  22.         for(int i=0;i<sizeList;i++) {//冒泡排序
  23.             for(int j=i;j<sizeList;j++) {
  24.                 if(dates[j].after(dates[i])) {
  25.                 Date temp = dates[i];//交换value
  26.                 dates[i] = dates[j];
  27.                 dates[j] = temp;
  28.                 Object objectTemp = keyObj[i];//交换key
  29.                 keyObj[i] = keyObj[j];
  30.                 keyObj[j] = objectTemp;
  31.                 }
  32.                
  33.             }
  34.         }
  35.         for(int i=0;i<keyObj.length;i++) {
  36.             System.out.println("key from array sorted----" + keyObj[i]);
  37.         }
  38.         for(int i=0;i<dates.length;i++) {
  39.             System.out.println("value from list sorted----" + dates[i]);
  40.         }
  41.         LinkedHashMap lhm = new LinkedHashMap();
  42.         for(int i=0;i<keyObj.length;i++) {//把经过排序的键值对放入Linked中
  43.             lhm.put(keyObj[i], dates[i]);
  44.         }
  45. /*
  46. *遍历Linkedhashmap打印出结果
  47. */
  48.         Set set1 = lhm.entrySet();
  49.         Iterator it = set1.iterator();
  50.         while(it.hasNext()) {
  51.             Map.Entry me = (Map.Entry)it.next();
  52.             System.out.println("key:" + me.getKey() + "----value" + me.getValue());
  53.         }
  54.     }

这种方法比较直观,可是效率比较低,而且对内存也很浪费,你想想,在这个过程中我们new了两个长度是hm.size()长度的数组,用于存放key和value,排序也是我们自己写的冒泡排序法~~



下面我介绍第二种方法:



第二种方法的思路是这样的,我们用hm.value()放回hm的vuale集合,再把它转换成一个数组,然后调用jdk给我们提供的Arrays.sort()方法去帮我们排序,这样效率会比自己写的冒泡排序法效率高的多!



在调用sort方法的时候我们需要写一个比较器,比较器的代码如下:





   1. package com.mgoann.test1;
   2.
   3. import java.util.Comparator;
   4. import java.util.Date;
   5.
   6. public final class DateComp implements Comparator {
   7.
   8.     public int compare(Object o1, Object o2) {
   9.         Date date1 = (Date)o1;
  10.         Date date2 = (Date)o2;
  11.         return date2.compareTo(date1);
  12.     }
  13.    
  14. }
15.

剩下的就是更具value去找相应的key的问题了~~这里我用了一个for循环和Iterator去查找hm里的key,找到以后我们就放到LinkedHashMap里~,详见例程:

   1. package com.mgoann.test1;
   2.
   3. import java.util.Arrays;
   4. import java.util.Collection;
   5. import java.util.Comparator;
   6. import java.util.Date;
   7. import java.util.HashMap;
   8. import java.util.Iterator;
   9. import java.util.LinkedHashMap;
  10. import java.util.Map;
  11. import java.util.Set;
  12.
  13. public class Sort {
  14.
  15.     /**
  16.      * @param args
  17.      */
  18.     public static void main(String[] args) {
  19.         HashMap<String, Date> hm = new HashMap<String, Date>();
  20.         LinkedHashMap<String, Date> linkedHM = new LinkedHashMap<String, Date>();
  21.         hm.put("1", new Date(8,10,1));
  22.         hm.put("3", new Date(8,10,3));
  23.         hm.put("2", new Date(8,10,2));
  24.         hm.put("5", new Date(8,10,5));
  25.         hm.put("9", new Date(8,10,9));
  26.         hm.put("8", new Date(8,10,8));
  27.         hm.put("6", new Date(8,10,6));
  28.         hm.put("7", new Date(8,10,7));
  29.         itHashMap(hm);
  30.         linkedHM = sortHashMap(hm);
  31.         itHashMap(linkedHM);
  32.     }
  33.
  34.     private static LinkedHashMap sortHashMap(HashMap<String, Date> hm) {
  35.        
  36.         LinkedHashMap<String, Date> linkedHM = new LinkedHashMap<String, Date>();
  37.         final Comparator DATE_COMP = new DateComp();
  38.                
  39.         int index = 0;
  40.            
  41.         Collection<Date> DateColl = hm.values();
  42.         Object[] dates = DateColl.toArray();
  43.         Arrays.sort(dates, DATE_COMP);
  44.         System.out.println("dates after sorted");
  45.         printElements(dates);
  46.         Set set = hm.entrySet();
  47.         for(int j=0;j<dates.length;j++) {
  48.             Iterator it = set.iterator();
  49.             while(it.hasNext()) {
  50.                 Map.Entry<String, Date> me = (Map.Entry<String, Date>)it.next();
  51.                 if(dates[j].equals(me.getValue())) {
  52.                     linkedHM.put(me.getKey(), me.getValue());
  53.                 }
  54.             }
  55.         }
  56.         return linkedHM;
  57.     }
  58.    
  59.     public static void printElements(Collection c) {
  60.         Iterator it = c.iterator();
  61.         while(it.hasNext()) {
  62.             System.out.println(it.next());
  63.         }
  64.     }
  65.    
  66.     public static void printElements(Object[] dates) {
  67.         for(int i=0;i<dates.length;i++) {
  68.             System.out.println(dates[i]);
  69.         }
  70.     }
  71.    
  72.     public static void itHashMap(Map<String, Date> m) {
  73.         Set set = m.entrySet();
  74.         Iterator it = set.iterator();
  75.         while(it.hasNext()) {
  76.             Map.Entry<String, Date> me = (Map.Entry<String, Date>)it.next();
  77.             System.out.println("key:" + me.getKey() + "----value:" + me.getValue());
  78.         }
  79.     }
  80. }

这样我们就实现了HashMap的排序问题!



程序运行结果如下:

key:3----value:Tue Nov 03 00:00:00 CST 1908
key:5----value:Thu Nov 05 00:00:00 CST 1908
key:7----value:Sat Nov 07 00:00:00 CST 1908
key:2----value:Mon Nov 02 00:00:00 CST 1908
key:9----value:Mon Nov 09 00:00:00 CST 1908
key:8----value:Sun Nov 08 00:00:00 CST 1908
key:6----value:Fri Nov 06 00:00:00 CST 1908
key:1----value:Sun Nov 01 00:00:00 CST 1908
dates after sorted
Mon Nov 09 00:00:00 CST 1908
Sun Nov 08 00:00:00 CST 1908
Sat Nov 07 00:00:00 CST 1908
Fri Nov 06 00:00:00 CST 1908
Thu Nov 05 00:00:00 CST 1908
Tue Nov 03 00:00:00 CST 1908
Mon Nov 02 00:00:00 CST 1908
Sun Nov 01 00:00:00 CST 1908
key:9----value:Mon Nov 09 00:00:00 CST 1908
key:8----value:Sun Nov 08 00:00:00 CST 1908
key:7----value:Sat Nov 07 00:00:00 CST 1908
key:6----value:Fri Nov 06 00:00:00 CST 1908
key:5----value:Thu Nov 05 00:00:00 CST 1908
key:3----value:Tue Nov 03 00:00:00 CST 1908
key:2----value:Mon Nov 02 00:00:00 CST 1908
key:1----value:Sun Nov 01 00:00:00 CST 1908
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics