【修真院java小课堂】HashMap浅析

大家好,我是IT修真院西安分院第三期学员,一枚正直纯洁善良的JAVA程序员。

今天给大家分享一下HashaMap
一、背景介绍

什么是HashMap

基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和 允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)此实现假定哈希函数将元素适当地分布在各桶之间,可 为基本操作(get 和 put)提供稳定的性能。迭代 collection 视图所需的时间与 HashMap 实例的 “容量”(桶的数 量)及其大小(键 - 值映射关系数)成比例。所以,如果迭代性能很重要, 则不要将初始容量设置得太高(或将加载 因子设置得太低)。

二、知识剖析

什么是Hash:


① 哈希查找是一种数据结构中用于 查找 的算法,相比于其他查找算法,他的时间复杂度更 低,所以在实际应用中大量采取了哈希表的方式,Hashmap 就是 java 内置的哈希查找的方法
② 哈希函数的基本思想: 将记录的存储地址和关键字之间建立一个确定的对应关系。这样,当想查找某条记录时,我们根据记录的关键字就可以得到它的存储地址,进而快速判断这条记录是否存在,存储在哪里。

③负载因子:负载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。。
④ 哈希函数的缺陷 + 改进方式: 在哈希存储中,不同的关键字可能映射到了相同的地址,这就叫产生冲突,我们必须相处冲突处理的方法。当然,前辈们已经相处了各种各样的方法,我在这里先不做深究。

Map是什么

Map 是 java 中的一个接口。它是 java 中的一种重要的数据结构。 Map 是从键 (关键字) 到值 (记录) 的映射, 键不允许重复, 每个键最多能映射一个值。 在 java 中,有很多类实现了 Map 接口,HashMap 就是其中的一个。

(01) HashMap 继承于 AbstractMap 类,实现了 Map 接口。Map 是 “key-value 键值对” 接口,AbstractMap 实现了 “键值对”
的通用函数接口。

(02) HashMap 是通过 “拉链法” 实现的哈希表。它包括几个重要的成员变量:table, size, threshold, loadFactor, modCount。

  table 是一个 Entry[] 数组类型,而 Entry 实际上就是一个单向链表。哈希表的"key-value 键值对 " 都是存储在 Entry 数组中的。

  size 是 HashMap 的大小,它是 HashMap 保存的键值对的数量。

  threshold 是 HashMap 的阈值,用于判断是否需要调整 HashMap 的容量。threshold 的值 =“容量 * 加载因子”,当 HashMap 中存储数据的数量达到
threshold 时,就需要将 HashMap 的容量加倍。

  loadFactor 就是加载因子。

  modCount 是用来实现 fail-fast 机制的。

三、常见问题
hash冲突
当关键字集合很大时,关键字值不同的元素可能会映像到哈希表的同一地址上,即 K1!=K2,但 f(K1)=f(K2), 这种现象称为 hash 冲突,实际中冲突是
不可避免的,只能通过改进哈希函数的性能来减少冲突。

四、解决方案
1. 开发定址法

2. 再哈希法

3. 链地址法

4. 建立一个公共溢出区

五、编码实战

六、扩展思考

hashMap线程安全吗

七、参考文献

Java核心技术卷一

八.更多讨论

  1. 什么是单向链表?

答:每个节点中只保存指向下一个节点的引用。

public class OrderLinkedList {

private Node head;

private class Node{
    private int data;
    private Node next;

    public Node(int data){
        data = data;
    }
}

public OrderLinkedList(){
    head = null;
}
//some code
}
  1. 什么是双向链表。

答:每个链节中保存了这个链节前后链节的引用。可以通过一个链节向前或向后查询。

public class TwoWayLinkedList {
private Node head;//表示链表头
private Node tail;//表示链表尾
private int size;//表示链表的节点个数

  private class Node{
      private Object data;
      private Node next;
      private Node prev;
      
      public Node(Object data){
          this.data = data;
      }
  }
  
  public TwoWayLinkedList(){
      size = 0;
      head = null;
      tail = null;
  }
  //some code
  }
  1. 双端链表和双向链表的差别?

答:双端链表的查询方向是头部–>尾部,和尾部–>头部。双向链表是每个链节都可以向两个方向查询。

今天的分享就到这里啦,欢迎大家点赞、转发、留言、拍砖~

技能树.IT修真院
“我们相信人人都可以成为一个工程师,现在开始,找个师兄,带你入门,掌控自己学习的节奏,学习的路上不再迷茫”。
这里是技能树.IT修真院,成千上万的师兄在这里找到了自己的学习路线,学习透明化,成长可见化,师兄1对1免费指导。

快来与我一起学习吧http://www.jnshu.com/login/1/28090500

你可能感兴趣的:(task)