Map

120 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情

HashMap

  • HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。
  • HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。
  • HashMap 是无序的,即不会记录插入的顺序。
  • HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

Hashtable

  • Hashtable是原始的java.util的一部分, 是一个Dictionary具体的实现 。
  • Hashtable实现了Map接口,Hashtable集成到了集合框架中。它和HashMap类很相似,但是它支持同步。
  • Hashtable存储内容也是键值对。当使用一个哈希表,要指定用作键的对象,以及要链接到该键的值,该键经过哈希处理,所得到的散列码被用作存储在该表中值的索引。

HashMap 和 Hashtable 的区别

  • Hashtable内部方法使用 synchronized 修饰修饰,线程安全,而HashMap是非线程安全。
  • Hashtable因为线程安全的问题所以效率比HashMap要低。
  • HashMap可以有null键和null值,虽然只能有一个null键。而Hashtable不能有null键和null值。Hashtable 容量默认的初始大小为 11,之后每次扩充,容量变为原来的 2n+1。HashMap默认的初始化大小为 16。之后每次扩充,容量变为原来的 2 倍。
  • HashMap 在解决哈希冲突时有了较大的变化,当链表长度大于阈值(默认为 8)时,将链表转化为红黑树,Hashtable没有。

HashSet

  • HashSet从HashMap而来,是一个不允许有重复元素的集合。
  • HashSet 可以有 null 值。
  • HashSet 数据无序
  • HashSet 实现 Set 接口。
  • HashSet 线程不安全,如果多个线程尝试同时修改 HashSet,最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。

TreeMap

TreeMap与HashMap类存储非常相似,都是键值对方式。TreeMap用一种排序顺序存储键/值对的方式进行存储,它是基于红黑树的NavigableMap实现的,这点是HashMap所没有的。

HashSet 如何检查重复

HashSet 会先计算对象的哈希值来决定对象存储的位置,同时每一次加入对象的都会计算其哈希值并进行比较,如果发现有哈希值相同的情况,则会调用equals()方法来检查 hashcode 相等的对象是否真的相同。如果相同,HashSet 就不会让加入操作成功。

扰动函数

所谓扰动函数指的就是 HashMap 的 hash 方法。使用 hash 方法也就是扰动函数是为了防止一些实现比较差的 hashCode() 方法,换句话说使用扰动函数之后可以减少碰撞。

HashMap 的底层实现

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。查询速度块,无序且不支持线程同步。HashMap 通过 key 的 hashCode 经过扰动函数处理过后得到 hash 值,然后通过 (n - 1) & hash 判断当前元素存放的位置(这里的 n 指的是数组的长度),如果当前位置存在元素的话,就判断该元素与要存入的元素的 hash 值以及 key 是否相同,如果相同的话,直接覆盖,不相同就通过拉链法解决冲突。

HashMap 多线程操作导致死循环问题

因为在并发下的 Rehash 会造成元素之间会形成一个循环链表从而造成死循。。并发环境下一般使用 ConcurrentHashMap。

HashMap 有哪几种常见的遍历方式

  • Iterator迭代器中EntrySet的方式遍历;
  • Iterator迭代器中KeySet的方式遍历;
  • For Each EntrySet 方式遍历;
  • For Each KeySet 方式遍历;
  • Lambda 表达式方式遍历;
  • Streams API 单线程方式遍历;
  • Streams API 多线程方式遍历。

ConcurrentHashMap

ConcurrentHashMap是JUC包下的并发容器之一,可以实现线程安全。ConcurrentHashMap由多个 Segment组合而成,Segment 相当于一个 HashMap 对象。Segment其中包含一个HashEntry 数组, HashEntry既是一个键值对,也是一个链表的头节点。

Collections作用:

  • 排序
  • 查找,替换操作
  • 同步控制

其中每个作用都有许多方法这里就不列举了。