黑马程序员技术交流社区

标题: HashMap是无序的? [打印本页]

作者: 黄玉昆    时间: 2013-2-25 17:35
标题: HashMap是无序的?
本帖最后由 黄玉昆 于 2013-2-25 22:00 编辑

我测试了一下,将几个元素无序加入到集合中,结果确实有序的,我记得毕老师的视频中说HashMap是无序的啊,而且基于哈希表的数据结构,也应该是无需的啊,为什么会有序呢?
  1. //keySet集合测试

  2. import java.util.*;
  3. class KeySetDemo
  4. {
  5.         public static void sop(Object obj)
  6.         {
  7.                 System.out.println(obj);
  8.         }

  9.         public static void main(String[] args)
  10.         {
  11.                 //创建Map集合,并添加元素
  12.                 Map<Integer,String> map = new HashMap<Integer,String>();
  13.                 //无序加入
  14.                 map.put(2,"zhangsan");
  15.                 map.put(6,"lisi");
  16.                 map.put(3,"wangwu");
  17.                 map.put(4,"heihei");
  18.                 map.put(5,"xixi");
  19.                
  20.                 //打印元素
  21.                 sop("原集合:" + map);
  22.                 sop("---------------------------------------");
  23.                 //获取map集合中的所有键的Set集合
  24.                 Set<Integer> keySet = map.keySet();
  25.                 //有了Set集合就可以获取其迭代器,取值
  26.                 Iterator<Integer> it = keySet.iterator();
  27.                 while (it.hasNext())
  28.                 {
  29.                         Integer i = it.next();
  30.                         String s = map.get(i);
  31.                         sop(i + " = " + s);
  32.                 }
  33.         }
  34. }
复制代码

HashMap结果.PNG (2.5 KB, 下载次数: 299)

HashMap结果.PNG

作者: 莫嘉伟    时间: 2013-2-25 17:44
占楼,目前想法还在测试中,个人认为是因为楼主你使用的KeySet是整型数的关系,HashMap的key对象必须实现hashCode()和equals()方法,而整型数的hashCode()方法··好吧这个我没研究过,不过应该是按整型数的大小进行排列的,equals()方法也是,毕竟都是个用了这么久的类型了,所以楼主把整型数作为KeySet的话HashMap可以保证其顺序,但是如果楼主用个自定义楼的话可能就无法保证了,毕竟重写过的hashCode()方法和equals()方法是千奇百怪的
作者: 王鹏伟    时间: 2013-2-25 17:47
特殊情况,Integer数值类型计算hashCode时返回的就是该值,所以会按照你存储的键(数值)大小排序。
作者: 黄玉昆    时间: 2013-2-25 17:57
莫嘉伟 发表于 2013-2-25 17:44
占楼,目前想法还在测试中,个人认为是因为楼主你使用的KeySet是整型数的关系,HashMap的key对象必须实现ha ...

并未重写,确实是Integer的问题,已经解决,谢谢。
作者: 黄玉昆    时间: 2013-2-25 17:58
王鹏伟 发表于 2013-2-25 17:47
特殊情况,Integer数值类型计算hashCode时返回的就是该值,所以会按照你存储的键(数值)大小排序。 ...

说的没错,果然是Integer的问题,灰常感谢
作者: 莫嘉伟    时间: 2013-2-25 18:12
另外补充一点就是我觉得HashMap的无法保证顺序意思应该是他无法保证元素是按你加进去的时候的顺序排列,实际上明显他还是有根据KeySet的hashCode()方法和equals()方法进行排序的,但排出来的就不一定是你加进去时的顺序 了,个人认为应该是这个意思
作者: 黑马刘杰    时间: 2013-2-25 18:26
本帖最后由 黑马刘杰 于 2013-2-25 18:29 编辑

我感觉你的测试值太小了,有可能hashCode在计算时hash表的长度大于你的最大值,所以hashCode计算完在hash表中存储的都是你输入的值,而不是对hash表长度取摸的值,如果让Integer值足够大的话就不会出现这种问题了。
  1. // 创建Map集合,并添加元素
  2.                 Map<Integer, String> map = new HashMap<Integer, String>();
  3.                 // 无序加入
  4.                 map.put(10000, "zhangsan");
  5.                 map.put(6, "lisi");
  6.                 map.put(1456, "wangwu");
  7.                 map.put(22342, "heihei");
  8.                 map.put(325, "xixi");
  9.                 map.put(3654, "xxx");

  10.                 // 打印元素
  11.                 sop("原集合:" + map);//原集合:{1456=wangwu, 325=xixi, 6=lisi, 22342=heihei, 10000=zhangsan, 3654=xxx}
复制代码
一句话,就是你的测试值key键的值太小了
作者: 黄玉昆    时间: 2013-2-25 22:00
本帖最后由 黄玉昆 于 2013-2-26 13:08 编辑
黑马姚凯歌 发表于 2013-2-25 21:53
我的理解是Integer实现了comparable接口,其本身具备比较型

嗯,确实是实现了Comparable,而且还复写了compareTo方法。谢谢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2