HashSet源码分析
HashSet源码分析
HashSet是Set的一个实现,Set定义一个集合,集合的一个特征是不能包含重复的元素(可以包含null),HashSet底层使用HashMap作为存储结构来实现。
可知HashSet只用来存储对象,并不是key-value对,因为HashMap中的key必须是不同的,跟集合的定义相同,
所以HashSet只使用HashMap中的key来存储元素,而value字段使用同一个常量对象PRESENT就可以了。
private static final Object PRESENT = new Object();
private transient HashMap<E,Object> map;
可知HashSet中判断将要被存储的元素是否已经存在集合中,被转移到HashMap中判断key值是否有重复,而key的判断逻辑如下:
//x,y是两个key
static boolean eq(Object x, Object y) {
return x == y || x.equals(y); }
那么到底要不要重写HashSet中对象的equals()方法呢?个人认为这个还是需要根据具体应用需求来决定,默认情况下equals()实现就是比较(x == y),重写以后就是比较两对象的属性值是否相等。
如果应用场景认为,两个对象相同的条件是指向同一个引用,就不需要重写equals()方法了。
如果应用场景认为,两个对象相同的条件是指内部属性值相同,就需要重写equals()方法了。
构造函数
//可知HashSet只用来存储对象,并不是key-value对,因为HashMap中的key必须是不同的,跟集合的定义 //相同,所以HashSet只使用HashMap中的key来存储元素,而value字段使用一个final Object PRESENT就可以 public HashSet() { map = new HashMap<E,Object>(); } //构造函数中指定底层HashMap的initialCapacity和loadFactor public HashSet(int initialCapacity, float loadFactor) { map = new HashMap<E,Object>(initialCapacity, loadFactor); } public HashSet(int initialCapacity) { map = new HashMap<E,Object>(initialCapacity); }
add()方法
public boolean add(E o) {
//value值为PRESENT对象,一个常量对象 return map.put(o, PRESENT)==null; }
remove()方法
public boolean remove(Object o) {
//map.remove(o)可能返回null,那就表示不存在目标Object o //删除失败 return map.remove(o)==PRESENT; }
contains()方法
public boolean contains(Object o) {
//到HashMap的Key中去查找目标对象O return map.containsKey(o); }
Iterator
//HashSet自己没有实现Iterator接口,而使用HashMap的实现
public Iterator<E> iterator() { return map.keySet().iterator(); }
上一篇: 到底什么样的人可以做外贸?
下一篇: redis集群搭建