A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 草莓味的可爱 初级黑马   /  2019-4-10 19:49  /  880 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

**LinkedList**:
    单向链表:
        存储一个元素,指向下一个元素的引用地址值
    双向链表:
        存储一个元素,指向下一个元素的引用地址值和指向上一个元素的引用地址值
    LinkedList采用的是双向链表;

**哈希算法**:
    通过key-value的格式,让key和value存在一种关系的算法,比如数组中的索引和元素的关系
**哈希表**:
    一种数据结构;
    用于hash算法存储的关系式的数据结构
**哈希冲突**:
    两个不同的地理值通过hash算法产生相同的key
   
**jdk1.8之前Hashmap**:
    组成:
        链表散列 //又称为数组+链表
    特点:
        通过key的扰动函数(hash方法)来判断键值对的键是否存在,如果键中的key和hashcode相等,则覆盖,不相等则通过拉链法解决冲突;
        对比jdk1.7的hash算法,jdk1.8的hash算法优化了一些,主要是jdk1.7的扰动函数动用了四次;
**jdk1.8之后HashMap**:
    组成:
        数组+链表+红黑树
    特点:
        链表法:
            将hash冲突的键值对存入数组中元素的链表(每个数组中的元素其实就是一个链表);
            当链表的阈值(默认为8即长度)修改为红黑树结构,便于链表的查询
   
**属性**:
    初始化容量:
        static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;  //16
    填充因子:
        static final float DEFAULT_LOAD_FACTOR = 0.75f;
    桶节点(链表长度大于设置的值修改为红黑树结构):
        static final int TREEIFY_THRESHOLD = 8;
    加载因子:
        final float loadFactor;
        概念:
            entry数组jdk-1.8之后又称为node数组,加载因子决定这个数组的疏密度,利用率,效率,趋近于0的时候,数组中存放的数据就小,趋近于1的时候数组中存放的数据就大;
            默认容量是16,默认的加载因子是0.75则容器在长度为16*0.75=12的时候则会进行扩容;
    临界值:      ****
        int threshold;
        概念:
            当实际大小超过(容量*填充因子)临界值时,则进行扩容
   
核心方法:
    构造方法:
        四个:
            HashMap() //默认的有参构造
            HashMap(Map<? extends K, ? extends V> m) //包含一个map的构造方法
            HashMap(int initialCapacity) //指定容量的构造函数
            HashMap(int initialCapacity, float loadFactor) //指定加载因子和容量的构造方法
    核心方法:
        hash()
            概念:
                将传进来的key计算出hashcode值,在对hashcode值进行高16 ^ 低16 运算,作为node数组的下标;
                static final int hash(Object key) {
                    int h;
                    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
                }
                初始化容量:
                    static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
                    这里的1>>4 其实使用位运算是效率高
        put()
            首先判断传进来的key-value作为一个node数组;
            判断是否需要扩容,resize() //要么初始化,要么扩容
            初始化后,采用if ((p = tab[i = (n - 1) & hash]) == null)
            n-1表示要填充的node[] 数组不能越界,并且计算出hash值
            
        get()
        resize()
            进行少使用,resize()非常消耗资源

面试题:
    为什么hashmap中的容量是2的次冥?
        答:
        因为是2的次冥,数组的散列就越大,碰撞几率就变小.

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马