zoukankan      html  css  js  c++  java
  • HashMap要点总结

    HashMap分析

    线性表:ArrayList

    ArrayList:进行节点的添加与删除的代价是非常高的:原因在于,当删除节点的时候他要把相应的节点后边的元素往前移一位覆盖掉之前的元素。增加一个节点同样如此。

    它的特殊导致我们经常犯一些错误:

             for (int i = 0; i < arrayList.size(); i++) {
                arrayList.remove(i);
            }
    

    这个例子就是典型的由于不够了解底层数据结构导致的错误。

           
    
    // 正确的操作  尾删除法,也可以使用头删法(删除index=0) 但是 头删法每次删除以后都要做一次前移操作很消耗资源
    		int size = arrayList.size();
             for (int i = 0; i < size; i++) {
                arrayList.remove(arrayList.size() - 1);
             }
    

    image-20210508145451554
    image-20210508145951458

    在Hashmap中定位元素在顺序表中的index采用了

    static int indexFor(int h, int length) {  //jdk1.7的源码,jdk1.8没有这个方法,但是实现原理一样的
         return h & (length-1);  //第三步 取模运算
    }
    

    顺序表的长度一般都为素数,这样做可以最大程度减小冲突发生的概率。

    但是为什么hashMap中的顺序表为2的倍数?

    这样做就是因为当它的长度为2的倍数时直接对长度-1 & hash 结果等于求模运算,这样效率更高。

    在JDK1.8的实现中,优化了高位运算的算法,通过hashCode()的高16位异或低16位实现的:(h = k.hashCode()) ^ (h >>> 16),主要是从速度、功效、质量来考虑的,这么做可以在数组table的length比较小的时候,也能保证考虑到高低Bit都参与到Hash的计算中,同时不会有太大的开销。

     static final int hash(Object key) {
            int h;
            return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
        }
    

    image-20210508185544426

  • 相关阅读:
    Jenkins中Jelly邮件模板的配置
    十天冲刺(10)
    代码大全阅读笔记01
    大二下学期学习进度(十)
    十天冲刺(9)
    十天冲刺(8)
    统计文章中字母、单词出现的频率
    十天冲刺(7)
    十天冲刺(6)
    十天冲刺(5)
  • 原文地址:https://www.cnblogs.com/FCY-LearningNotes/p/14799787.html
Copyright © 2011-2022 走看看