博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
3. JDK Map
阅读量:6266 次
发布时间:2019-06-22

本文共 3610 字,大约阅读时间需要 12 分钟。

  hot3.png

JDK Map

Map接口中的方法

  1. 判断系。containsKey包含元素、containsValue包含值、isEmpty是否为空。
  2. 读取系。size大小、get获取元素
  3. 增删系。put增加、remove删除、putAll增加所有、clear清空。
  4. 转化系。entrySet返回键值对、、keySet返回键集合、values返回值集合。

Map下面的抽象类与接口

  1. AbstractMap AbstractMap中包含两个键值对类,SimpleImmutableEntrySimpleEntry前者初始化之后,不可修改值,后面不是。 简单实现了Map接口中的方法,
  2. ConcurrentMap ConcurrentMap中增加了两个替换replace、一个如果没有就设置putIfAbsent、一个移除键值remove四个方法。主要实现类为ConcurrentHashMap
  3. SortedMap SortedMap排序的Map,增加了头keyfirstKey,尾keylastKey,切片方法headMaptailMapsubMap、还有一个比较器comparator
  4. NavigableMap SortedMap子接口,新增一系列Navigable的方法,能访问有序Map中的第一个、最后一个、返回比入参大,入参小的等等,这里不细说。
  5. ConcurrentNavigableMap ConcurrentMap与NavigableMap的接合。

Map中的内部类

  1. Cellections中,SynchronizedSortedMapSynchronizedMapCheckedSortedMapCheckedMapEmptyMap。在JDK中集合的辅助类中已经说过。
  2. ConcurrentSkipListMap中的SubMapConcurrentSkipListMap的分段类
  3. TreeMap中的AscendingSubMapDescendingSubMap。分段类,升序与降序两种。

HashMap

内部原理

HashMap内部数据结果是数组+链表。 根据map的key的hash值,进行一系列的算法,最后模得数组中的下标,如果下标链表中有实体里,那就把这个元素放到链表的最前面。 数组大小是固定,所以需要动态扩容,是扩容却不是动态定内部数组大小,所以如果先放大,最后删除,但是数组大小不会缩小。 可以看到HashMapnull的key与value都有处理。

动态配置初始化大小

内部静态类Holder中可以配置初始化数组的大小jdk.map.althashing.threshold

modCount的作用

ArrayList一样,HashMap中也有modCount字段,同样的作用。

逃脱

因为是HashMap,所以元素放到map中的位置与对象的hash有关,所以在对象改变了hash值,就算对象引用没有变,也会每次放到不同的位置,换句话说,一个对象可以放在同一个map的不同位置。

public class Mappest {    public int id;    public String name;    public Mappest(int id, String name) {        this.id = id;        this.name = name;    }    @Override    public int hashCode() {        return id + name.hashCode();    }    @Override    public boolean equals(Object obj) {        if(!(obj instanceof Mappest)){            return false;        }        Mappest m2 = (Mappest) obj;        if(this.hashCode() == m2.hashCode()){            return true;        }        return false;    }    public static void main(String[] args) {        HashMap
map = new HashMap<>(); Mappest mada = new Mappest(1, "mada"); map.put(mada, "1"); mada.id = 2; map.put(mada, "2"); for (Map.Entry en : map.entrySet()) { System.out.println(en.getValue()); } }}

HashTable

内部原理

HashMap的同步版本,synchronized同步方法。内部原理与HashMap类似。

TreeMap

内部原理

实现了NavigableMap接口。对外提供已排序的数组,内部使用的是红黑树结构(详细见这片)。 实例化TreeMap两种情况,一是Map元素实现java.lang.Comparable,二是java.util.Comparator比较器。

modCount

好吧,TreeMap中也有这个东东,作用类型。

AscendingSubMap与DescendingSubMap

AscendingSubMapDescendingSubMap表示升序,降序子Map。这里的升序是针对ComparableComparator而言,所以降序也只是反序ComparableComparator。 红黑树所有结点是有序存储。是升序,降序是对迭代顺序的。TreeMap是正序,所以在DescendingSubMap中,使用了Collections中的reverseOrder方法。

WeakHashMap

HashMap的WeakReference版本,WeakHashMap内部维护一个ReferenceQueue<Object>的数组,内部Entry继承WeakReference<Object>,通过WeakReference与ReferenceQueue配合实现了弱引用缓存,可以看这篇

LinkedHashMap

LinkedHashMap继承HashMap。内部使用HashMap储存数据,但是同时维持一个双向链表,用于记录访问顺序。 如果accessOrder为true。访问get方法,也会调整顺序:将被访问的元素,挪到顺序链表的表尾。

Properties

Properties继承Hashtable。用于读取properties文本。 借助XMLUtils读取xml文件。

EnumMap

枚举Map,Key只能是传入的枚举类实例。内部使用数组存储数据,而存取元素下标是枚举元素的ordinal,这样就没有下标计算过程,效率更高。

public V put(K key, V value) {   typeCheck(key);   int index = key.ordinal();   Object oldValue = vals[index];   vals[index] = maskNull(value);   if (oldValue == null)       size++;   return unmaskNull(oldValue);}

同样,也没有逃逸的问题。

IdentityHashMap

IdentityHashMap的内部结构与HashMap内部结构不同。

  1. 前者使用数组存储,后者使用数组+链表。
  2. 前者使用key相同(==),后者是相等(equal)。这样就不存在HashMap中逃脱的情节。
  3. 前者的下标如果存在实体,就会往下找一个有两个空的下标,将相同的两个实体都放入。

ConcurrentHashMap

ConcurrentHashMap内部将所有数据放到Segment数组中,而Segment中有HashEntry数组。所以是数组+数组格式。 Segment继承ReentrantLock,与HashTable不同,ConcurrentHashMap的锁对象不是整个Map,而是Segment

ConcurrentSkipListMap

TreeMap的同步版本。

转载于:https://my.oschina.net/markho/blog/808003

你可能感兴趣的文章
[LeetCode] Decode String 解码字符串
查看>>
数字逻辑的一些基本运算和概念
查看>>
ant重新编译打包hadoop-core-1.2.1.jar时遇到的错
查看>>
【★★★★★】提高PHP代码质量的36个技巧
查看>>
3 weekend110的配置hadoop(格式化) + 一些问题解决 + 未免密码配置
查看>>
JavaScript Creating 对象
查看>>
Java compiler level does not match the version of the installed Java project facet.(转)
查看>>
WPF MediaElement.Position属性
查看>>
sqoop数据迁移(基于Hadoop和关系数据库服务器之间传送数据)
查看>>
spring mysql多数据源配置
查看>>
[React] Override webpack config for create-react-app without ejection
查看>>
检索 COM 类工厂中 CLSID 为{00024500-0000-0000-C000-000000000046} 的组件时失败,原因是出现以下错误: 80070005。...
查看>>
测试java的父子类化
查看>>
HDOJ 1008
查看>>
安装thrift出现的一些问题
查看>>
makefile编写---单个子目录编译模板
查看>>
Oracle DB_LINK如何使用
查看>>
cv resource
查看>>
关于加快INSERT语句执行速度和HINT /*+ append */及/*+ append nologging */的使用
查看>>
JDK源代码学习系列07----Stack
查看>>