背景:有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 这个大小,但是建议不要用这种方式去做排序。