ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

HashSet源码学习

2022-02-19 14:02:40  阅读:168  来源: 互联网

标签:map HashMap HashSet Object initialCapacity 学习 源码 new


一.介绍

1.HashSet

2.HashSet和HashMap的区别

1.相同点

  • HashSet 内部使用 HashMap 存储元素,对应的键值对的键为 Set 的存储元素,值为一个默认的 Object 对象。
  • HashSet和HashMap都是采用Hash算法来决定其元素的存储
  • 都不是同步的

2.不同点

  • HashSet实现了Set接口

    HashMap实现了Map接口

3.fast-fail

  • 快速失败(fail—fast)在用迭代器遍历一个集合对象时,如果遍历过程中集合对象中的内容发生了修改(增加、删除、修改),则会抛出ConcurrentModificationException
  • 迭代器在遍历时直接访问集合中的内容,并且在遍历过程中使用一个 modCount 变量。集合在被遍历期间如果内容发生变化,就会改变 modCount 的值。每当迭代器使用hasNext()/next() 遍历下一个元素之前,都会检测 modCount 变量是否为expectedmodCount 值,是的话就返回遍历值;否则抛出异常,终止遍历。
  • java.util包下的集合类都是快速失败的,不能在多线程下发生并发修改(迭代过程中被修改)。

二.源码部分

1.基本属性

继承AbstractSet:它实现了Set接口中的大部分函数。从而方便其它类实现Set接口。

Cloneable是标记型的接口,它们内部都没有方法和属性,实现 Cloneable来表示该对象能被克隆

Set 接口中的方法和 Collection 中方法一致的。Set 接口取出方式只有一种, 迭代器 。

java.io.Serializable接口:

可以启用其序列化功能。未实现次接口的类无法使其任何状态序列化或反序列化。可序列化类的所有子类型本身都是可序列化的。

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    //定义序列化ID
    static final long serialVersionUID = -5024744406713321676L;
    //存储数据的map
    private transient HashMap<E,Object> map;

    // Dummy value to associate with an Object in the backing Map 与后台映射中的对象关联的虚拟值
    private static final Object PRESENT = new Object();

2.构造函数

    /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * default initial capacity (16) and load factor (0.75).
     * 构造一个新的空集;HashMap实例具有默认的初始容量(16)和负载因子(0.75)。
     */
    public HashSet() {
        map = new HashMap<>();
    }
    /**
     * Constructs a new set containing the elements in the specified collection.
     * 构造包含指定集合中的元素的新集合
     * The <tt>HashMap</tt> is created with default load factor
     * (0.75) and an initial capacity sufficient to contain the elements in
     * the specified collection.
     * 创建的HashMap带有默认负载因子(0.75)和初始容量,初始容量足以包含指定集合中的元素。
     * @param c the collection whose elements are to be placed into this set
     * @throws NullPointerException if the specified collection is null
     */
    public HashSet(Collection<? extends E> c) {
        //?
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        //将集合c加入
        addAll(c);
    }
    /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * the specified initial capacity and the specified load factor.
     * 建造指定容量和负载因子的空集合
     * @param      initialCapacity   the initial capacity of the hash map
     * @param      loadFactor        the load factor of the hash map
     * @throws     IllegalArgumentException if the initial capacity is less
     *             than zero, or if the load factor is nonpositive
     */
    public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<>(initialCapacity, loadFactor);
    }
    /**
     * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has
     * the specified initial capacity and default load factor (0.75).
     * 构造指定初始容量的集合
     * @param      initialCapacity   the initial capacity of the hash table
     * @throws     IllegalArgumentException if the initial capacity is less
     *             than zero
     */
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }
//构造的是LinkedHashMap,该方法不对外公开,是提供给LinkedHashSet使用的
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

3.contains(Object o)

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

4.add(E e)

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

5.remove(Object o)

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

三.总结

  1. HashSet怎么不重复?
  • 通过存储元素的 hashCode 方法和 equals 方法来确定元素是否重复。

标签:map,HashMap,HashSet,Object,initialCapacity,学习,源码,new
来源: https://www.cnblogs.com/ftfty/p/15912420.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有