哎呦我, HashMap KeySet有序? 好像是哈

背景:有8个格子,上架物品时需要从第一个格子开始上架,不能跳格子,也就是说 如果格子1空着,就不能把物品放到格子2。有这么个顺序的情况

前人模块功能实现: 用HashMap 初始化格子信息,然后用 KeySet() 去遍历找到第一个空的格子。

印象中HashMap 是无序的啊!!!
仔细想想,HashMap 是数组 + 链表 + 红黑树, 因为Hash的原因无法保证插入顺序等于KeySet 遍历顺序。但是 相同的一组数据无论插入顺序怎么样,遍历顺序都是一样的。因为存储的结果是一样的嘛。

回到这里看,key为1 ~ 8的8个格子放到HashMap 中,初始size 为16 ,不会出现Hash冲突的情况,那就是数组结构中 1 ~ 8分别占据1个桶,又因为 1 ~ 8 的Hash值逐渐增加,所以——有序!!! 这个真的,我服了 orz.

来测试一下我们的猜想:


    public static void main(String[] args) {
//        System.out.println(new Match().match("aaa".toCharArray(), "a.a".toCharArray()));

        HashMap<String, String> map = new HashMap<String, String>();
        map.put("1", "1格子");
        map.put("2", "2格子");
        map.put("3", "3格子");
        map.put("4", "4格子");
        map.put("5", "5格子");
        map.put("6", "6格子");
        map.put("7", "7格子");
        map.put("8", "8格子");
//        map.put("9", "9格子");
//        map.put("10", "10格子");
//        map.put("11", "11格子");

        for (String position: map.keySet()) {
            System.out.println(position  + ", Hash:" + position.hashCode() + ", " + map.get(position));
        }
    }

输出是这样的
在这里插入图片描述
有意思嗨!看插入这里果然是
在这里插入图片描述
拿出笔来算算啊
49: 110001 & 1111 = 0001 桶
50: 110010 & 1111 = 0010 桶
51: 110011 & 1111 = 0011 桶
52: 110100 & 1111 = 0100 桶
53: 110101 & 1111 = 0111 桶
54: 110110 & 1111 = 0110 桶
55: 110111 & 1111 = 0111 桶
56: 111000 & 1111 = 1000 桶
……

这里确实能满足这个场景的需求,那这里的扩展性呢?产品一旦扩格子,就废了,因为这个最多支持到10 内有序!还是不要这么玩了(如果是炫技,那你赢了)

如下扩到11 个格子的时候就不行了,因为 “11” 的hash 是1568
11000100000 & 1111 = 0000 桶,顺序就没了
在这里插入图片描述
哎,这里的Key现在是 String 类型,用Int类型的话Hash 是不是就又有序了!
来试试

public static void main(String[] args) throws IOException {
//        System.out.println(new Match().match("aaa".toCharArray(), "a.a".toCharArray()));

        HashMap<Integer, String> map = new HashMap<Integer, String>();

        for (int i = 1; i < 1000; i ++) {
            map.put(i, i + "格子");
        }

        File file = new File("out.log");
        FileWriter fw = new FileWriter(file);
        int lastVal = 0;
        for (Integer position: map.keySet()) {
            fw.write(position  + ", Hash:" + position.hashCode() + ", " + map.get(position) + "\n");
            if (lastVal > position) {
                System.err.println(lastVal + "," + position);
            }
            lastVal = position;

//            System.out.println(position  + ", Hash:" + position.hashCode() + ", " + map.get(position));
        }
    }

在这里插入图片描述
那这种场景下Int类型到多大就保证不了顺序呢?

答案是65537 和 65536 的顺序就颠倒了。

虽然目前这个业务的格子数不太可能扩到65536 这个大小,但是建议不要用这种方式去做排序。

  • 10
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值