关于 java.util.HashSet<E> 的部分笔记。HashSet集合是一个不会存储重复元素、遍历元素顺序无法保证的集合实现。本文演示代码段的执行环境基于JDK版本1.7。
概述
HashSet是一个以HashMap为底层数据结构的集合实现类,该实现类实现了Set接口中规定的集合处理方法API,而且允许存储null元素。HashSet集合具有集合内元素唯一,且无序的特点。由于底层数据结构依赖于散列表,所以HashSet的add(E e)、remove(Object o)、contains(Object o)、size()等方法可以实现常量时间的操作性能。
HashSet是一个非线程安全的实现。如果需要在多线程环境使用HashSet进行操作,那么要么使用线程安全的实现类,要么对HashSet集合做一些额外的处理来保证HashSet集合可以满足多线程环境中的使用需求。常见的一种实现方式是:
1 | Set s = Collections.synchronizedSet(new HashSet(...)); |
同样,HashSet集合返回的迭代器也含有快速失败检查,如果在遍历当前HashSet集合的过程中对集合做了结构化修改,那么就会抛出ConcurrentModificationException。同样的,HashSet集合也无法保证可以捕捉到所有的并发修改操作。
继承关系
1 | // HashSet<E> |
实现接口
类名 | 实现接口 |
---|---|
HashSet<E> | Iterable<E>, Collection<E>, Set<E>, Serializable, Cloneable |
HashSet
Constructor Summary
public HashSet()
1 | public HashSet() { |
初始化一个空的set集合。底层依赖的hashmap的初始容量为16,加载因子是0.75。
public HashSet(Collection<? extends E> c)
1 | public HashSet(Collection<? extends E> c) { |
初始化一个空set集合,并将集合c中的内容存储到set集合中。底层hashmap的初始容量由集合c中存储的元素数量决定。之后调用的addAll(Collection<? extends E> c)方法为AbstractCollection中实现的方法,内部调用了HashSet覆盖的父类方法add(E e)。
public HashSet(int initialCapacity, float loadFactor)
1 | public HashSet(int initialCapacity, float loadFactor) { |
初始化一个空的set集合。底层依赖的hashmap的初始容量为initialCapacity,加载因子值是loadFactor。
public HashSet(int initialCapacity)
1 | public HashSet(int initialCapacity) { |
初始化一个空的set集合。底层依赖的hashmap的初始容量为initialCapacity,加载因子值是默认的0.75。
HashSet(int initialCapacity, float loadFactor, boolean dummy)
1 | HashSet(int initialCapacity, float loadFactor, boolean dummy) { |
初始化一个空的set集合。底层依赖的hashmap的初始容量为initialCapacity,加载因子值是loadFactor。这个构造方法中多了一个参数dummy,这个参数除了区别构造方法之外没有其他用处,但是该构造方法返回了一个LinkedHashMap,在LinkedHashSet<E>中使用该构造方法来实现一个基于链表的Set集合。
部分方法
public Iterator<E> iterator()
1 | public Iterator<E> iterator() { |
返回一个可以遍历当前HashSet集合的迭代器。该迭代器在遍历元素时不保证元素遍历的先后顺序。底层实际调用的是map中keySet集合的迭代器。
public int size()
1 | public int size() { |
返回当前HashSet集合存储的元素数量。底层实际调用的是map的size()方法完成操作。
public boolean isEmpty()
1 | public boolean isEmpty() { |
判断当前HashSet集合是否为空。如果为空返回true,否则返回false。底层实际调用的是map的isEmpty()方法完成操作。
public boolean contains(Object o)
1 | public boolean contains(Object o) { |
判断当前HashSet集合中是否含有元素o。如果存在返回true,否则返回false。底层实际调用的是map的containsKey(Object key)方法完成操作。
public boolean add(E e)
1 | public boolean add(E e) { |
将元素e加入到当前HashSet集合中。如果元素e是第一次被加入到集合中,那么由于map的put(E key, Object value)方法会返回该key在加入之前的value值,所以会返回null,所以第一次加入元素e时当前方法会返回true。如果非第一次加入,那么map的put(E key, Object value)会返回一个非null对象,所以当前方法会返回false。
public boolean remove(Object o)
1 | public boolean remove(Object o) { |
将元素o从当前HashSet集合中删除。由于在向map集合中存储元素时,key为当前HashSet集合存储的元素自身,value是一个初始化的Object对象,所以在调用map的remove(Object key)方法会返回该key在加入之前的value值,所以第一次删除元素时返回true。如果当前元素o被多次调用了remove(Object o)方法,那么第二次及之后就返回false。
public void clear()
1 | public void clear() { |
清空HashSet集合的所有元素。底层实际调用的是map的clear()方法完成操作。
public Object clone()
1 | public Object clone() { |
克隆复制一个HashSet集合对象。该过程分两步进行,首先复制一个HashSet集合对象自身,接着复制HashSet集合底层的map结构,最后返回复制得到的对象。
private void writeObject(java.io.ObjectOutputStream s)
1 | private void writeObject(java.io.ObjectOutputStream s) |
将当前HashSet执行序列化操作并写入到流中。自定义方法,在执行序列化过程时会采用HashSet自己实现的过程来完成序列化操作。
private void readObject(java.io.ObjectInputStream s)
1 | private void readObject(java.io.ObjectInputStream s) |
从流中取出序列化的数据内容并反序列化成内存中的一个HashSet对象。自定义方法,在执行反序列的过程时会用HashSet自己实现的过程来完成反序列过程。
涉及基础知识点
- NIL
参考文献
- NIL