1. HashSet介绍
HashSet继承Set集合,所以它存储元素的特点也是无序不可重复,实际上HashSet集合在new的时候,底层实际上是创建了一个HashMap集合,向HashSet集合中存储元素,实际上是存储到HashMap集合中。
2. HashSet数据结构
public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
HashSet继承于AbstractSet,并且实现了Set接口。
3. HashSet源码
//向HashSet中存储元素实际上是存储到HashMap中 private transient HashMap<E,Object> map; //向Set中添加元素实际是向HashMap中添加,但是HashMap中元素是键值对的,因为HashSet只是使用了key部分,而value部分固定使用PERSENT private static final Object PRESENT = new Object(); //默认构造方法 public HashSet() { //底层创建HashMap map = new HashMap<>(); } //指定集合的构造方法 public HashSet(Collection<? extends E> c) { //HasSet默认大小是16,加载因子0.75,总是从Math.max((int) (c.size()/.75f) + 1, 16)中选择出最大的数作为初始化容量。 map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16)); addAll(c); } //指定容量和加载因子的构造方法 public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<>(initialCapacity, loadFactor); } //指定容量的构造方法 public HashSet(int initialCapacity) { map = new HashMap<>(initialCapacity); } //调用iterator实际是调用HashMap的key集合的迭代器 public Iterator<E> iterator() { return map.keySet().iterator(); } public int size() { return map.size(); } public boolean isEmpty() { return map.isEmpty(); } public boolean contains(Object o) { return map.containsKey(o); } //添加元素到Set中,实际调用HashMap的put方法,只是添加了key部分,value部分总是使用PRESENT public boolean add(E e) { return map.put(e, PRESENT)==null; } //删除HashSet中的元素o public boolean remove(Object o) { return map.remove(o)==PRESENT; } public void clear() { map.clear(); }
4. HashSet实例
public class HashSetTest01 { public static void main(String[] args) { HashSet<String> set = new HashSet<>(); set.add("a"); set.add("b"); set.add("c"); set.add("d"); System.out.println(set.size()); System.out.println(set.contains("a")); System.out.println(set.contains("ff")); set.remove("d"); System.out.println(set.size()); Iterator<String> it = set.iterator(); while (it.hasNext()){ String key = it.next(); System.out.println(key); } set.clear(); System.out.println(set.isEmpty()); } }