LinKedHashMap和TreeMap介绍
文章目录
- 前言
- 一、LinKedHashMap源码分析:
- 继承关系:
- 属性:
- 构造器:
- 私有内部类
- put 方法:
- LinKedHashMap总结
- 二、TreeMap源码分析:
- 继承关系:
- 属性:
- 构造器:
- 私有内部类
- 方法:
- TreeMap总结:
前言
我们对LinKedHashMap和TreeMap研究都是基于HashMap为参考来研究一下他们独有的特点,和维护这些特点的方法。
提示:以下是本篇文章正文内容,下面案例可供参考
一、LinKedHashMap源码分析:
LinKedHashMap继承自HashMap<K,V> 具有HashMap的所有特性:Key不能重复、Key value都可以为null 线程不安全
相比HashMap来说LinkedHashMap具有有序性(插入有序)
继承关系:
public class LinkedHashMap<K,V>extends HashMap<K,V>implements Map<K,V>
可以看出LinkedHashMap是基于HashMap实现的
属性:
默认值、扩容机制都和HashMap的特征一样
特有的属性:
transient LinkedHashMap.Entry<K,V> head;//头结点
transient LinkedHashMap.Entry<K,V> tail;//尾结点
构造器:
构造器调用HashMap的构造器
新增一个构造器:
boolean型的accessOrder 用来判断顺序性
true 访问有序 false 插入有序 默认值:false
public LinkedHashMap(int initialCapacity,float loadFactor,boolean accessOrder) {super(initialCapacity, loadFactor);this.accessOrder = accessOrder;}
私有内部类
Entry<K,V>内部类继承与HashMap的内部类Node 增加了 head tail 用来保证有序性。
注释:插入有序即 按照插入时的顺序保持有序 访问有序即访问后将此数据移动到末尾。
static class Entry<K,V> extends HashMap.Node<K,V> {Entry<K,V> before, after; //前缀和后缀Entry(int hash, K key, V value, Node<K,V> next) {super(hash, key, value, next);}}
put 方法:
直接使用put方法调用的是父类的put方法但在put方法里面调用的newNode方法是子类重写的
public V put(K key, V value) {return putVal(hash(key), key, value, false, true);}
inal V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;//判断数组是否为空,为空则对tab进行扩容扩容后将新数组的长度赋值给n。if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;//判断此hash对应的数组位置是否为Null 如果为null 用子类newNode方法赋值if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;//先判断链表首位的hash和此新传入的hash是否相等在判断k值是否相等,相等的话将首尾p赋值给eif (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;//判断p是否在红黑树上else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {//不在红黑树也不在首位的话遍历链表for (int binCount = 0; ; ++binCount) {//如果遍历到末尾给末尾赋值新创建的newNide;if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);//如果遍历到链表长度之外的话if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1sttreeifyBin(tab, hash);break;}//如果hash值与链表中以为hash值相等或者K值相等的话退出循环if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;//更新pp = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}//子类:Node<K,V> newNode(int hash, K key, V value, Node<K,V> e) {新建一个Entry 赋值给 P LinkedHashMap.Entry<K,V> p =new LinkedHashMap.Entry<>(hash, key, value, e);使用linkNodeLast方法对p进行重新操作(更新头结点,尾结点和前缀后缀等属性)linkNodeLast(p);return p;}
private void linkNodeLast(LinkedHashMap.Entry<K,V> p) {LinkedHashMap.Entry<K,V> last = tail;tail = p;//如果尾结点为null说明此链表之前没有Entry<K,V>将p赋值给头结点head// 否则更新p的前缀为之前的尾结点原来尾结点的后缀更新为Pif (last == null)head = p;else {p.before = last;last.after = p;}}
LinKedHashMap总结
从上面我们可以看出LinKedHashMap相比于HashMap保证的数据的有序性,他的有序性保证是在HashMap原有的基础上给每个数据添加了双向链表来达到数据的有序性
二、TreeMap源码分析:
TreeMap保证map的key可以大小排序,key不能为null (NullPointerException)value可以为null,key不能重复
继承关系:
继承AbstractMap所有方法
实现了 NavigableMap和Serializable(可序列化)接口
public class TreeMap<K,V>extends AbstractMap<K,V>implements NavigableMap<K,V>, Cloneable, java.io.Serializable
我们来介绍一下 NavigableMap主要作用就不分析源码了
1. NavigableMap 继承自 SortedMap,所以它的元素是有序的。
2. 在 SortedMap 基础上,支持快速搜索符合条件的最近的元素。这里条件主要是指 lower(>), floor(>=), ceiling(<),higher(>)。
3. 支持逆序访问。 descendingKeySet / descendingMap。
4. 支持获取子集合,集合边界元素是否包含是可配的 subMap headMap tailMap 。
通过上述我们就可以知道TreeMap同样也具备如上的功能
属性:
public Comparator<? super K> comparator() { //比较器return comparator;}private transient Entry<K,V> root = null; //root属性,红黑树的根节点,是entry类型entry节点根据key进行排序
构造器:
相比于HashMap来说提供了比较器用来对数据进行排序
//空参构造器使用默认比较器
public TreeMap() {comparator = null;}
//实现comparator的构造器public TreeMap(Comparator<? super K> comparator) {this.comparator = comparator;}//传入数据的构造器 public TreeMap(Map<? extends K, ? extends V> m) {comparator = null;putAll(m);}//带有comparator方法的类 public TreeMap(SortedMap<K, ? extends V> m) {comparator = m.comparator();try {buildFromSorted(m.size(), m.entrySet().iterator(), null, null);} catch (java.io.IOException | ClassNotFoundException cannotHappen) {}}
私有内部类
相比较HashMap来说内部类Entry增加了左右孩子父节点还有颜色的属性来实现红黑树储存数据
static final class Entry<K,V> implements Map.Entry<K,V> {K key; //键V value; //值Entry<K,V> left; //左孩子Entry<K,V> right; //右孩子Entry<K,V> parent; //父节点boolean color = BLACK; //颜色 默认黑色Entry(K key, V value, Entry<K,V> parent) {this.key = key;this.value = value;this.parent = parent;}
方法:
因为TreeMap继承自NavigableMap的所以也具有他的一些方法:
lower(>), floor(>=), ceiling(<),higher(>) //快速查找
descendingKeySet / descendingMap //逆序访问
subMap headMap tailMap //获取子集合
TreeMap总结:
TreeMap底层是基于红黑树实现了,所以他支持快速查询方法 并且它的构造器可传入了比较器可以自定义数据的排序方法
LinKedHashMap和TreeMap介绍相关推荐
- Java—Map集合详解(HashMap/Hashtable/LinkedHashMap/Properties/TreeMap/WeakHashMap/IdentityHashMap/EnumMap)
关注微信公众号:CodingTechWork,一起学习进步. Map Map集合介绍 Map(也称为字典.关联数组)是用于保存具有映射关系的数据,保存两组值,key和value,这两组值可以是任何 ...
- Java(ArrayList和LinkedList)、(HashTable与HashMap)、(HashMap、Hashtable、LinkedHashMap和TreeMap比较)
1.ArrayList和LinkedList (1)ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构. (2)对于随机访问get和set,ArrayList绝 ...
- HashMap, LinkedHashMap 和 TreeMap的区别
HashMap, LinkedHashMap 和 TreeMap的区别 Java里面的HashMap, LinkedHashMap 和 TreeMap 有什么区别?我看不出以下3个key和value有 ...
- HashMap、LinkedHashMap、TreeMap的深入认识
HashMap,LinkedHashMap,TreeMap都属于Map. Map 主要用于存储键(key)值(value)对,根据键得到值,因此键不允许键重复,但允许值重复. HashMap 是一个最 ...
- 有序Map集合:LinkedHashMap和TreeMap该如何选用
文章目录 前言 一.为什么HashMap是无序的 二.LinkedHashMap如何保证有序性 三.TreeMap的底层原理 四.LinkedHashMap和TreeMap比较 总结 前言 为什么Ha ...
- java treemap 内存_Java中Map、HashMap、LinkedHashMap、TreeMap的区别
Map: Map是一个接口不能实例化,Map接口主要有两个实现类:HashMap和TreeMap类.其中,HashMap类按哈希算法来存取对象,而TreeMap类可以对键对象进行排序: Map提供了一 ...
- Java中HashMap、LinkedHashMap和TreeMap区别使用场景
1. HashMap中k的值没有顺序,常用来做统计. 2.LinkedHashMap吧.它内部有一个链表,保持Key插入的顺序.迭代的时候,也是按照插入顺序迭代,而且迭代比HashMap快. 3. T ...
- Java之HashMap、Hashtable、LinkedHashMap、TreeMap、ConcurrentHashMap简单的区别
一. HashMap 1)底层实现 数组+链表+红黑树(在JDK1.8中如果链表长度大于8的时候才转换为红黑树) 2)是否线程安全 不支持线程的同步,线程不安全,如需同步,可用Collections ...
- LinkedHashMap和TreeMap的有序性
做一个数组的多属性动态排序的功能,使用map时发现有序性问题. LinkedHashMap会存储数据的插入顺序,是进入时有序:TreeMap则是默认key升序,是进入后有序(hashMap .hash ...
最新文章
- mysql数据库报错1146_关于MySQL报错:[ERR] 1146
- 让容器跑得更快:CPU Burst 技术实践
- GenericUDF使用流程记载(转载+自己整理)
- java多线程流式写入文件夹_java多线程写入同一文件
- java中白盒测试用例_基于JAVA开发的中国象棋游戏的开发与研究白盒测试用例.doc...
- 面试精讲之面试考点及大厂真题 - 分布式专栏 09 缓存必问:Reids持久化,高可用集群
- 2017.7.26 奇怪的道路 失败总结
- fastdfs删除过期文件_Spring Boot 系列:使用 Spring Boot 集成 FastDFS
- apipost提示error:invalid protocol的解决方案
- android中搭建NDK环境及使用JNI技术
- 如何调整金格电子章服务器印章_电子签章赋能勘察设计新动力
- 用c#转换word或excel文档为html文件,C#实现DataSet内数据转化为Excel和Word文件的通用类完整实例...
- garmone build on sb2
- Synergy——使用一套键鼠控制两台电脑(Ubuntu 和 Windows)
- java单循环赛制程序_单循环比赛的固定轮转编排法与贝格尔编排法
- 计算机桌面图标损坏,win7系统的电脑桌面图标受到损坏要如何修复
- 前端vue地图自动定位当前位置
- 计算机动画原理课程设计选题,组成原理课程设计设计一台模型计算机.pdf
- 深析Vue双向数据绑定(MVVM模型)
- 娱乐之神兽羊驼(原创)