Map集合:HashMap、TreeMap

HashMap

HashMap是基于哈希表的Map接口的非同步实现。实现HashMap对数据的操作,允许有一个null键,多个null值。

HashMap底层就是一个数组结构,数组中的每一项又是一个链表。数组+链表结构,新建一个HashMap的时候,就会初始化一个数组。Entry就是数组中的元素,每个Entry其实就是一个key-value的键值对,它持有一个指向下一个元素的引用,这就构成了链表,HashMap底层将key-value当成一个整体来处理,这个整体就是一个Entry对象。HashMap底层采用一个Entry【】数组来保存所有的key-value键值对,当需要存储一个Entry对象时,会根据hash算法来决定在其数组中的位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry对象时,也会根据hash算法找到其在数组中的存储位置, 在根据equals方法从该位置上的链表中取出Entry;

hashmapput.png

put:(key-value)方法是HashMap中最重要的方法,使用HashMap最主要使用的就是put,get两个方法。

判断键值对数组table[i]是否为空或者为null,否则执行resize()进行扩容;
根据键值key计算hash值得到插入的数组索引 i ,如果table[i] == null ,直接新建节点添加即可,转入6,如果table[i] 不为空,则转向3;
判断table[i] 的首个元素是否和key一样,如果相同(hashCode和equals)直接覆盖value,否则转向4;
判断table[i] 是否为treeNode,即table[i]是否为红黑树,如果是红黑树,则直接插入键值对,否则转向5;
遍历table[i] ,判断链表长度是否大于8,大于8的话把链表转换成红黑树,进行插入操作,否则进行链表插入操作;便利时遇到相同key直接覆盖value;
插入成功后,判断实际存在的键值对数量size是否超过了threshold,如果超过,则扩容;

也可参考HashSetput过程:
https://www.jianshu.com/p/419a448414da

get方法取值过程:

int  hash = key.hashCode();

int index =  hash%Entry[].length;

指定key通过hash函数得到key的hash值;
调用内部方法getNode(),得到桶号(一般为hash值对桶数求摸);
比较桶的内部元素是否和key相等,如不相等,则没有找到,相等,则取出相等记录的value;
如果得到key所在桶的头结点恰好是红黑树节点,就调用红黑树节点的getTreeNode()方法,否则就遍历链表节点。getTreeNode()方法通过调用树形节点的find()方法进行查找。由于之前添加时已经保证这个树是有序的,因此查找时基本就是折半查找,效率高;
如果对比节点的哈希值和要查找的哈希值相等,就会判断key是否相等,相等就直接返回;不相等就从子树中递归查找;
HashMap中直接地址用hash函数生成,冲突用比较函数解决。如果每个桶内部只有一个元素,那么查找的时候只有一次比较。当许多桶内没有值得时候,许多查询就会更快

addEntry方法

  1. 添加新元素前,判断是否需要对map的数组进行扩容,如果需要扩容,则扩容多大?
  2. 对于新增key-value键值对,如果可以的hash值相同,则构造单向列表;

TreeMap

实现了SortedMap接口,是一个有序的集合,是一个红黑树接口,每个key-vlaue作为红黑树的节点,没有指定顺序则是根据key执行自然排序。默认自然排序

  • 继承了AbstractMap类,实现了接口

implements NavigableMap<K,V>, Cloneable, java.io.Serializable
可以自然排序,可以定制排序,Entry root = null 红黑树的根节点;size存放键值对的数量。

  • 自然排序:所有的key必须实现Comparable接口,所有的key都是同一类的对象;
  • 定制排序:创建TreeMap对象传入一个Comparator对象,改对象负责key进行排序,采用定制排序不要去key实现comparable接口。

    • 自定义排序时候,需要将Comparator对象传进集合中当作参数,进而进行排序。Comparator的对象也需要传进两个实体类对象,进行两两比较。,return 比较的结果,如果是正数就是从下到大排序,等于0说明两个数的一摸一样,直接去重,如果是负数,说明一个数小,此刻return返回一个负数,排序的是时候么就是按照倒序排序的。
  • 主要方法:

put():
get():根据不同的排序比较方法定位需要的数据,检索速度时间复杂度为O(log(n));

remove():

TreeMap默认是自然排序,没有查找方法;无需遍历

  • 红黑树

是一个更高效检索二叉树,每个节点只能是红色或者黑色;根节点永远是黑色;所有叶子的子节点都是空节点,并且都是黑色;每个红色节点的两个子节点都是黑色,没有连续的红色节点;从人一个节点到其子树中的每个叶子节点的路径中所包含相同数量的黑色节点。

HashMap和TreeMap比较

(1)HashMap:适用于在Map中插入、删除和定位元素。 默认乱序
(2)Treemap:适用于按自然顺序或自定义顺序遍历键(key)。 默认自然排序,如果插入的是基本类型,按照 大小排序。如果是引用类型,则按照插入顺序
(3)HashMap通常比TreeMap快一点(树和哈希表的数据结构使然),建议多使用HashMap,
在需要排序的Map时候才用TreeMap.**
(4)HashMap 非线程安全 TreeMap 非线程安全
(5)HashMap的结果是没有排序的,而TreeMap输出的结果是排好序的。

在HashMap中通过get()来获取value,通过put()来插入value,ContainsKey()则用来检验对象是否已经存在。可以看出,和ArrayList的操作相比,HashMap除了通过key索引其内容之外,别的方面差异并不大。

Treemap的方法是在hashmap的基础上进行补充的

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,367评论 6 512
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,959评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,750评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,226评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,252评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,975评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,592评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,497评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,027评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,147评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,274评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,953评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,623评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,143评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,260评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,607评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,271评论 2 358