JAVA集合系列之-HashSet
1. HashSet 简介
- HashSet 是个包装HashMap的一种数据结构,HashSet的大部分的方法都是依靠找HashMap的方法,在内部结构没有特别复杂的实现,在方法的实现中没有synchronized关键字修饰,所以是线程不安全的
- HashSet继承了AbstractMap、实现了Map、Cloneable、Serializable接口
- 继承了AbstractMap的接口,HashSet就有了增、删、改、查、判空、迭代器等功能
- 实现了Cloneable接口则说明HashSet支持Object的clone的方法,如果不继承调用clone方法会抛出CloneNotSupportedException的错误,看了下源码,是native方法实现的
- 实现了Serializable接口则说明HashSet能够被序列化和反序列化,能够在网络中进行传输
2. HashSet 数据结构
HashSet的继承关系
java.lang.Object ↳ java.util.Map<E> ↳ java.util.AbstractMap<E> ↳ java.util.HashSet<E> public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {}
3. HashSet 主要方法说明
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable { // 使用 HashMap 的 key 保存 HashSet 中所有元素 private transient HashMap<E,Object> map; // 定义一个虚拟的 Object 对象作为 HashMap 的 value private static final Object PRESENT = new Object(); ... // 初始化 HashSet,底层会初始化一个 HashMap public HashSet() { map = new HashMap<E,Object>(); } // 以指定的 initialCapacity、loadFactor 创建 HashSet // 其实就是以相应的参数创建 HashMap public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<E,Object>(initialCapacity, loadFactor); } public HashSet(int initialCapacity) { map = new HashMap<E,Object>(initialCapacity); } HashSet(int initialCapacity, float loadFactor, boolean dummy) { map = new LinkedHashMap<E,Object>(initialCapacity , loadFactor); } // 调用 map 的 keySet 来返回所有的 key public Iterator<E> iterator() { return map.keySet().iterator(); } // 调用 HashMap 的 size() 方法返回 Entry 的数量,就得到该 Set 里元素的个数 public int size() { return map.size(); } // 调用 HashMap 的 isEmpty() 判断该 HashSet 是否为空, // 当 HashMap 为空时,对应的 HashSet 也为空 public boolean isEmpty() { return map.isEmpty(); } // 调用 HashMap 的 containsKey 判断是否包含指定 key //HashSet 的所有元素就是通过 HashMap 的 key 来保存的 public boolean contains(Object o) { return map.containsKey(o); } // 将指定元素放入 HashSet 中,也就是将该元素作为 key 放入 HashMap public boolean add(E e) { return map.put(e, PRESENT) == null; } // 调用 HashMap 的 remove 方法删除指定 Entry,也就删除了 HashSet 中对应的元素 public boolean remove(Object o) { return map.remove(o)==PRESENT; } // 调用 Map 的 clear 方法清空所有 Entry,也就清空了 HashSet 中所有元素 public void clear() { map.clear(); } ... }
4. HashSet 总结
- 内部实现是使用HashMap进行实现,
- 线程不安全
- 存放数据是无序的
- 存放的数据是唯一的