基本特性:

  • 维持健值对的集合接口,健不可以重复,每一个健只能映射到一个值。
  • Map替代了原来的虚拟类Directory。
  • Map提供了三种集合视角,keys(KeySet),values(Values),entries(key-value)(EntrySet),Map元素的顺序体现于遍历器返回的Map元素顺序。
  • 需要注意的是,不可以用可变的元素作Map的健,这会影响到equals对键值的操作,例如,不可以使用Map自身作为key,但是可以作为value。
  • 一些Map的实现对key-value有特殊的要求,如key不可以为null。
HashMap:
 
查找索引:
 
jdk1.7 数组散列结构:
 
/**
* Returns index for hash code h.
*/
static int indexFor(int h, int length) {
// assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
return h & (length-1);
}
 
length为2的n次方的情况下,length-1 则二进制末尾为1,“&” 操作计算结果末尾位置与h二进制末尾相同(否则,末尾为0,和任何数的 “&” 操作,末尾都为0,散列性降低,易发生碰撞),定位索引的位置优劣取决于哈希函数生成哈希值的散列均匀程度。
 
h & (length -1) 相当于 h % length 但前者性能优于后者
 
 
jdk1.8
 
final Node<K,V> getNode(int hash, Object key) {
    Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
    if ((tab = table) != null && (n = tab.length) > 0 &&
        (first = tab[(n - 1) & hash]) != null) {
...
 
索引策略同1.7
 
 
map 容量: 2的n次方
 
jdk1.7:指定 initialCapacity 则为 initialCapacity,不指定则为 DEFAULT_INITIAL_CAPACITY 16
 
涉及需要扩展容量时:
/**
* Inflates the table.
*/
private void inflateTable(int toSize) {
    // Find a power of 2 >= toSize 找到一个大于等于toSize的2的n次方数
    int capacity = roundUpToPowerOf2(toSize);
 
    threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
    table = new Entry[capacity];
    initHashSeedAsNeeded(capacity);
}
 
private static int roundUpToPowerOf2(int number) {
    // assert number >= 0 : "number must be non-negative";
    int rounded = number >= MAXIMUM_CAPACITY
            ? MAXIMUM_CAPACITY
            : (rounded = Integer.highestOneBit(number)) != 0
                ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded
                : 1;
 
    return rounded;
}
 
 
jdk1.8: 如果指定初始容量 initialCapacity 则通过tableSizeFor 优化容量,如果不指定,则默认为 DEFAULT_INITIAL_CAPACITY 16;
 
构造函数:
 
public HashMap(int initialCapacity, float loadFactor) {
    if (initialCapacity < 0)
        throw new IllegalArgumentException("Illegal initial capacity: " +
                                           initialCapacity);
    if (initialCapacity > MAXIMUM_CAPACITY)
        initialCapacity = MAXIMUM_CAPACITY;
    if (loadFactor <= 0 || Float.isNaN(loadFactor))
        throw new IllegalArgumentException("Illegal load factor: " +
                                           loadFactor);
    this.loadFactor = loadFactor;
    this.threshold = tableSizeFor(initialCapacity);
}
...
/**
* 生成一个2的n次方数最为目标容量
* Returns a power of two size for the given target capacity.
* Hackers Delight, sec 3.2  章节3.2介绍的上舍入算法
*/
static final int tableSizeFor(int cap) {
    int n = cap - 1;
    n |= n >>> 1;
    n |= n >>> 2;
    n |= n >>> 4;
    n |= n >>> 8;
    n |= n >>> 16;
    return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
 
容量调整时,需要调用 tableSizeFor。
 
碰撞:
 
jdk1.7:使用数组散列,索引到同一位置的不同元素,使用链表存储,碰撞元素插入链表头部。
 
jdk1.8: TREEIFY_THRESHOLD 变量控制使用链表还是树,当链表节点数达到 TREEIFY_THRESHOLD(默认8),改为使用红黑树存储碰撞元素。
 
ConcurrentHashMap:
 
jdk1.7 segment 分段加锁
 
jdk1.8 synchronized(synchronized (f) ); cas(casTabAt)
 
TreeMap:
 
红黑树:
 
满足特定红黑性质的二叉搜索树,区别于平衡二叉树(AVL:左右子树高度差不能超过1),近似平衡(任何路径不能长于最小路径的2倍),节点增加color数据位(其它为k、left、right)。
 
节点标为红色,黑色
 
根节点时黑色的
 
每个叶节点(NIL)为黑色
 
如果一个节点为红色,则它的两个子节点为黑色
 
对于每个节点,从该节点到其所有后代叶节点的简单路径上,均包含相同数目的黑色节点,黑节点个数成为黑高。
 
 

JAVA Map 之元素定位,冲突碰撞的更多相关文章

  1. 《手把手教你》系列技巧篇(十四)-java+ selenium自动化测试-元素定位大法之By xpath上卷(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大.  使用这种方法几乎可以定位到页面上的任意元素. ...

  2. 《手把手教你》系列技巧篇(十五)-java+ selenium自动化测试-元素定位大法之By xpath中卷(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大.  使用这种方法几乎可以定位到页面上的任意元素. ...

  3. 《手把手教你》系列技巧篇(十六)-java+ selenium自动化测试-元素定位大法之By xpath下卷(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍定位倒数二个方法:By xpath.xpath 的定位方法, 非常强大.  使用这种方法几乎可以定位到页面上的任意元素. ...

  4. 《手把手教你》系列技巧篇(十七)-java+ selenium自动化测试-元素定位大法之By css上卷(详细教程)

    1.简介 CSS定位方式和xpath定位方式基本相同,只是CSS定位表达式有其自己的格式.CSS定位方式拥有比xpath定位速度快,且比CSS稳定的特性.下面详细介绍CSS定位方式的使用方法.xpat ...

  5. 《手把手教你》系列技巧篇(十八)-java+ selenium自动化测试-元素定位大法之By css中卷(详细教程)

    1.简介 按计划今天宏哥继续讲解倚天剑-css的定位元素的方法:ID属性值定位.其他属性值定位和使用属性值的一部分定位(这个类似xpath的模糊定位). 2.常用定位方法(8种) (1)id(2)na ...

  6. 《手把手教你》系列技巧篇(十九)-java+ selenium自动化测试-元素定位大法之By css下卷(详细教程)

    1.简介 按计划今天宏哥继续讲解css的定位元素的方法.但是今天最后一种宏哥介绍给大家,了解就可以了,因为实际中很少用. 2.常用定位方法(8种) (1)id(2)name(3)class name( ...

  7. java selenium (五) 元素定位大全

    页面元素定位是自动化中最重要的事情, selenium Webdriver 提供了很多种元素定位的方法.  测试人员应该熟练掌握各种定位方法. 使用最简单,最稳定的定位方法. 阅读目录 自动化测试步骤 ...

  8. 《手把手教你》系列技巧篇(九)-java+ selenium自动化测试-元素定位大法之By name(详细教程)

    1.简介 上一篇宏哥已经介绍了通过id来定位元素,今天继续介绍其他剩下的七种定位方法中的通过name来定位元素.本文来介绍Webdriver中元素定位方法之By name,顾名思义,就是我们想要定位的 ...

  9. 《手把手教你》系列技巧篇(十一)-java+ selenium自动化测试-元素定位大法之By tag name(详细教程)

    1.简介 按宏哥计划,本文继续介绍WebDriver关于元素定位大法,这篇介绍By ClassName.看到ID,NAME这些方法的讲解,小伙伴们和童鞋们应该知道,要做好Web自动化测试,最好是需要了 ...

随机推荐

  1. IOS9中使用NSURLConection发送异步网络请求

    IOS9中使用NSURLConection发送异步网络请求 在ios9中,NSURLConection的sendSync..和sendAsync已经过时.被NSURLSession代替. 以下蓝色部分 ...

  2. 使用Storyboard拖线容易出错的地方

    使用Storyboard拖线容易出错的地方: 在Storyboard中,选中某个控件,按住ctrl键进行拖线,建立Outlet和Action后,不能手动再去修改自动生成的代码,然后再次进行连线,这样会 ...

  3. Oracle的分析函数

    Oracle的分析函数row_number(),rank(),dense_rank()的用法与区别 比如查询工资排名第7的员工信息,可以用分析函数来做. --查询工资排名第7的员工信息select * ...

  4. lead over 和 lag over

    今天在熟悉项目的某个功能模块时,查看mybatis的映射文件内发现这样的一串sql: (T.NET_VALUE - LEAD(T.NET_VALUE)OVER(ORDER BY T.ESTIMATE_ ...

  5. iOS- CoreData 数据库管理利器!

    1.前文 上次用SQLite3实现了数据管理,这次准备用CoreData来实现. Core Data 是iOS SDK 里的一个很强大的框架,允许程序员以面向对象的方式储存和管理数据.使用Core D ...

  6. iOS 文件下载及断点续传

    ios的下载我们可以使用的方法有:NSData.NSURLConnection.NSURLSession还有第三方框架AFNetworking和ASI 利用NSData方法和NSURLConnecti ...

  7. python名称空间介绍

    python名称空间介绍 名称空间 python 中名称空间分三种: 内置名称空间 全局名称空间 局部名称空间 内置名称空间: 原码里面的一些函数都是存在这个内存空间中,任何模块均可访问它,它存放着内 ...

  8. animation(动画)设置

    1.animation 动画 概念:当您在 @keyframes 中创建动画时,请把它捆绑到某个选择器,否则不会产生动画效果. 通过规定至少以下两项 CSS3 动画属性,即可将动画绑定到选择器: 规定 ...

  9. git创建使用1https://blog.csdn.net/Hanani_Jia/article/details/77950594

    这篇文章是我自己写的关于GitHub的内容,从我刚听到这个直到设置成功每一步都有详细的步骤来解释,其中有一些截图或者代码来自于网上. 首先,我先对GitHub来一个简单的介绍,GitHub有一个很强大 ...

  10. php 算法(二分法)只适用于有序表,且限于顺序存储结构

    function demo($array,$low,$high,$k){ if($low<=$high){//判断该数组是否存在 $mid =  intval(($low+$high)/2 ); ...