Java源码分析之HashSet

Set特性

1、唯一性:集合中的元素保证唯一
2、无序性:集合中的元素输出顺序不保证与输入顺序一致

类定义

public class HashSet<E> 
    extends AbstractSet<E>  
    implements Set<E>, Cloneable, java.io.Serializable

其中 Set 继承自 Iterable,所以HastSet拥有的特性有

  1. 可迭代
  2. 可拷贝
  3. 可序列化

实现

private transient HashMap<E,Object> map;        
private static final Object PRESENT = new Object();

首先可以看到HashSet中有两个实例变量,这两个变量是实现HashSet逻辑的关键。

HashMap 是 HashSet 的底层实现,transient 关键字是用于去除序列化(了解更多可参考Java基础之transient关键字

再看看几个关键的方法实现

public int size() {
    return map.size();
}

public boolean isEmpty() {
    return map.isEmpty();
}

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

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

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

每个方法都很简单,熟悉HashMap的同学应该很好理解,就是利用了HashMap的键唯一的特性,因为HashMap使用了hash函数,所以要想保证唯一,就必须得保证hashCode和equals共同标记唯一性。

因为Object类的hashCode方法是对对象的物理地址进行hash求值,所以每个对象的hash值肯定不一样,如果要想让对象使用属性值判断对象是否相等,就必须得重写hashCode以及equals方法。

总结

  1. HashSet 内部使用 HashMap 实现,使用 hashCode 以及 equals 方法共同保证唯一性

题外话

重写hashCode以及equals方法也是有坑的,具体可以参考《effictive java》,里面讲的比较清晰。

猜你喜欢

转载自blog.csdn.net/gongm24/article/details/80274369