• JDK 1.8源码阅读 HashSet


    一,前言

      类实现Set接口,由哈希表支持(实际上是一个 HashMap集合)。HashSet集合不能保证的迭代顺序与元素存储顺序相同。HashSet集合,采用哈希表结构存储数据,保证元素唯一性的方式依赖于:hashCode()与equals()方法。

    二,HashSet结构

      2.1 什么是哈希表 

        哈希表底层使用的也是数组机制,数组中也存放对象,而这些对象往数组中存放时的位置比较特殊,当需要把这些对象给数组中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在数组中的位置,然后把这个对象存放在数组中。而这样的数组就称为哈希数组,即就是哈希表。

        当向哈希表中存放元素时,需要根据元素的特有数据结合相应的算法,这个算法其实就是Object类中的hashCode方法。由于任何对象都是Object类的子类,所以任何对象有拥有这个方法。即就是在给哈希表中存放对象时,会调用对象的hashCode方法,算出对象在表中的存放位置,这里需要注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

      2.2 哈希表存储结构

    三,HashSet源码阅读

      3.1 HashSet的继承关系

       

      3.2 HashSet的构造方法

    public HashSet() {}  // 一个空的构造函数,new一个hashMap对象实例出来。默认初始容量是16 加载因子是0.75,
    public HashSet(Collection<? extends E> c) {} // 将一个新的collection转换为一个HashSet集合
    public HashSet(int initialCapacity, float loadFactor) {} // 自己初始化容量和加载因子的大小
    public HashSet(int initialCapacity) {} // 初始化容量大小,加载因子用默认的

      3.3 HashSet的常用方法

    public Iterator<E> iterator() {}  // 转化成迭代器
    
    public int size() {} // 基础集合长度
    
    public boolean isEmpty() {} // 判断是否为空
    
    public boolean contains(Object o) {} // 判断对象是否存在
    
    public boolean add(E e) {} // 添加
    
    public boolean remove(Object o) {} // 删除
    
    public void clear() {} // 清空
    
    @SuppressWarnings("unchecked")
    public Object clone() {} // 克隆
      
    /**
     * @since 1.8
     */
    public Spliterator<E> spliterator() {} // 1.8

    四,总结

      保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。它是一个无序的集合(元素存与取的顺序可能不同),它不能存储重复的元素

  • 相关阅读:
    SSL 1579——泽泽在巴西
    SSL 1644——取数字问题
    SSL 1589——火车票
    SSL 1506——打鼹鼠
    SSL 1212——大厅安排
    洛谷 1064——金明的预算方案(动态规划的背包问题)
    SSL 1463——公共子串
    SSL 1461——最大连续数列的和
    SSL 1643——最小乘车费用
    SSL 1460——最小代价问题
  • 原文地址:https://www.cnblogs.com/tashanzhishi/p/10617069.html
Copyright © 2020-2023  润新知