• HashMap原理和TreeMap原理


    http://www.importnew.com/7099.html及文章下方评论

    http://blog.csdn.net/vking_wang/article/details/14166593超赞

    http://blog.csdn.net/ghsau/article/details/16890151容量加载因子

    HashMap数据结构用数组和链表形式实现:

    每个数组中存储的是链表的头元素。每个元素是个entry,包含键和值。

    hashmap的get(key)方法得到的是key对应的value,并不是key-value键值对。

    用了hashing(哈希算法)来查找???(目前来看查找没有完全用哈希算法)

    调用put方法存储元素时,会先调用hashcode()方法返回键的hashcode,键的hashcode对数组的长度进行取余运算,得到的值便是桶的位置,比如两个元素的key的hashcode为12和28,数组长度为16,取余的结果都是12,将一起存储在数组下标为12的位置,存储entry实体(不是只存储值哦)。之后调用Map.entry可以获取。

    上面hashcode为12和28的key,其对应实体往下标相同的数组中put时怎么put?任何一个元素进来存在数组(数组中存的是最后一个插入的元素),并且该数组的元素有entry属性,其中的next会指向前一个存在数组中的元素。

    HashMap有两个参数影响其性能:初始容量和加载因子。默认初始容量是16还是2的冪次????,加载因子是0.75。容量是哈希表中桶(Entry数组)的数量。初始容量是哈希表创建时的容量,加载因子是哈希表在其容量自动增加前可以达到多满的一种尺度。当哈希表中条目数????超出了加载因子与当前容量的乘机,通过调用rehash方法将容量翻倍。

    void addEntry(int paramInt1, K paramK, V paramV, int paramInt2)
    {
    Entry localEntry = this.table[paramInt2];
    this.table[paramInt2] = new Entry(paramInt1, paramK, paramV, localEntry);
    if (this.size++ >= this.threshold)
    resize(2 * this.table.length);
    }

    覆盖和哈斯算法,16还是2的冪次???????concurrentHashMap和hashtable的区别,set存相同的情况,覆盖equals()需要覆盖hashCode()?

    对hashcode()方法进行再哈希的原因:

    本身hashcode是一个int型的值,取值范围有40多亿空间。只要哈希函数映射比较均匀松散,一般不会出现哈希碰撞。但是!由于想把各个对象均匀的分不到hashmap的桶中,因此需要对hashcode做取模运算,取模运算保留的是低位区的数字,比如hashmap桶的数量为16时,对hashcode取模保留的是低四位的数字。对于两个对象的hashcode,32位的hashcode一样的情况少,但它们的低四位一样的情况概率挺大的,因此必须对hashcode的低位增加随机性。可以直接对低位使用随机函数,因此采用高低位进行异或运算来增加低位的随机性,以便对象可以在不同的桶中随机分布。

    java中%表示取余

    取余和取模的区别是:在计算商时,取余向正方向舍入得到商,取模则是向负方向舍入得到商。(取模运算必须至少用一个double型做除法,两个int型的数除法只是取整,整数取模的结果有问题)

    当除数与被除数的符号相同时,rem和mod的结果是完全相同的;当除数与被除数的符号不相同时,结果不同。
    具体说,rem结果的符号与被除数相同;mod结果的符号与除数相同。
     
    hashmap中添加元素:
    public V put(K key, V value) {
         // 若“key为null”,则将该键值对添加到table[0]中。
             if (key == null) 
                return putForNullKey(value);
         // 若“key不为null”,则计算该key的哈希值,然后将其添加到该哈希值对应的链表中。
             int hash = hash(key.hashCode());
         //搜索指定hash值在对应table中的索引
             int i = indexFor(hash, table.length);
         // 循环遍历Entry数组,若“该key”对应的键值对已经存在,则用新的value取代旧的value。然后退出!
             for (Entry<K,V> e = table[i]; e != null; e = e.next) { 
                 Object k;
                  if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { //如果key相同则覆盖并返回旧值
                      V oldValue = e.value;
                     e.value = value;
                     e.recordAccess(this);
                     return oldValue;
                  }
             }
         //修改次数+1
             modCount++;
         //将key-value添加到table[i]处
         addEntry(hash, key, value, i);
         return null;}


    hashset添加元素

    public boolean add(E paramE)
    {
    return this.map.put(paramE, PRESENT) == null;
    }

    由此知当hashset添加重复元素会返回null(因为hashmap添加key相同的元素时更新value后返回原始value而不是null)

     

    hashmap根据key获取元素:

    2)get

    
    
     public V get(Object key) {
    
    
            if (key == null)
    
    
                return getForNullKey();
    
    
            int hash = hash(key.hashCode());
    
    
            //先定位到数组元素,再遍历该元素处的链表(hashcode无法直接定位到元素的地址)
    
    
            for (Entry<K,V> e = table[indexFor(hash, table.length)];
    
    
                 e != null;
    
    
                 e = e.next) {
    
    
                Object k;
    
    
                if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
    
    
                    return e.value;
    
    
            }
    
    
            return null;
    
    
    }
     
    hash():
    static final int hash(Object key) {
    int h;
    
    
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
    
    
    }
    hashcode右移16位左边补0后与原hashcode异或运算增加低位随机性。 


    TreeMap
    TreeMap基于红黑树实现
    主要用于存入元素的时候对元素进行自动排序,迭代输出的时候就按排序顺序输出。
    TreeMap中key不能为null
    http://www.cnblogs.com/wzyxidian/p/5204879.html
    新生的小心情
  • 相关阅读:
    Luogu 1080 【NOIP2012】国王游戏 (贪心,高精度)
    Luogu 1314 【NOIP2011】聪明的质检员 (二分)
    Luogu 1315 【NOIP2011】观光公交 (贪心)
    Luogu 1312 【NOIP2011】玛雅游戏 (搜索)
    Luogu 1525 【NOIP2010】关押罪犯 (贪心,并查集)
    Luogu 1514 引水入城 (搜索,动态规划)
    UVA 1394 And Then There Was One / Gym 101415A And Then There Was One / UVAlive 3882 And Then There Was One / POJ 3517 And Then There Was One / Aizu 1275 And Then There Was One (动态规划,思维题)
    Luogu 1437 [HNOI2004]敲砖块 (动态规划)
    Luogu 1941 【NOIP2014】飞扬的小鸟 (动态规划)
    HDU 1176 免费馅饼 (动态规划)
  • 原文地址:https://www.cnblogs.com/jianmianruxin/p/7505694.html
Copyright © 2020-2023  润新知