JDK源码分析——HashSet

Posted rain4j

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDK源码分析——HashSet相关的知识,希望对你有一定的参考价值。

目录

HashSet概述

??从前面开始,已经分析过集合中的List和Map,今天来介绍另一种集合元素:Set。这是JDK对HashSet的介绍:

This class implements the Set interface, backed by a hash table (actually a HashMap instance). It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time. This class permits the null element.

??大意是HashSet实现了Set接口,实际上是借助HashMap来实现的,HashSet不保证迭代时顺序,也不保证存储的元素的顺序保持不变。HashSet允许插入Null。介绍了HashSet的两个特点:无序,允许插入空值。

继承结构

技术分享图片

  • Set 是继承于Collection的接口。它是一个不允许有重复元素的集合。
  • HashSet继承AbstractSet,Abstract继承于AbstractCollection,AbstractCollection实现了Set中的绝大部分函数,为Set的实现类提供了便利。HashSet实现Set接口借助了HashMap。

内部字段及构造方法

内部字段

    //序列化
    static final long serialVersionUID = -5024744406713321676L;

    //通过HashMap实例实现Set接口
    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map
    //存入HashMap中键值对的值
    private static final Object PRESENT = new Object();

构造方法

    public HashSet() {
        map = new HashMap<>();
    }

    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }

存储元素

??调用了HashMap的put方法插入以插入元素e为键,Object对象PRESENT为值的键值对,通过比较返回值是否为null判断插入是否成功,因为HashMap的put方法插入的键值对已经存在,那么它会返回键值对的值,也就是PRESENT;如果不存在就返回null。从而实现不能插入重复值。HashMap的put方法返回:the previous value associated with key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with key.)

    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }

删除元素

??调用HashMap的remove方法

    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

包含元素

??调用HashMap的containsKey方法查找是否存在以当前元素作为key的键值对

    public boolean contains(Object o) {
        return map.containsKey(o);
    }

总结

??HashSet比较简单,它存储元素是无序的,可以插入null,基于HashMap实现,所以它也是线程不安全的。

以上是关于JDK源码分析——HashSet的主要内容,如果未能解决你的问题,请参考以下文章

JDK源码分析——HashSet

jdk源码分析——HashSet

集合之HashSet(含JDK1.8源码分析)

HashSet源码分析 jdk1.6

Java提高篇——通过分析 JDK 源代码研究 Hash 存储机制

JDK源码分析-Collection