HashSet源码学习
2022/2/19 14:42:45
本文主要是介绍HashSet源码学习,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
一.介绍
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; }
三.总结
- HashSet怎么不重复?
- 通过存储元素的 hashCode 方法和 equals 方法来确定元素是否重复。
这篇关于HashSet源码学习的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-26Mybatis官方生成器资料详解与应用教程
- 2024-11-26Mybatis一级缓存资料详解与实战教程
- 2024-11-26Mybatis一级缓存资料详解:新手快速入门
- 2024-11-26SpringBoot3+JDK17搭建后端资料详尽教程
- 2024-11-26Springboot单体架构搭建资料:新手入门教程
- 2024-11-26Springboot单体架构搭建资料详解与实战教程
- 2024-11-26Springboot框架资料:新手入门教程
- 2024-11-26Springboot企业级开发资料入门教程
- 2024-11-26SpringBoot企业级开发资料详解与实战教程
- 2024-11-26Springboot微服务资料:新手入门全攻略