类图
源码
构造方法
public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, java.io.Serializable
{
//存储数据的对象,由此就可以看书HashSet是HashMap来实现的
private transient HashMap<E,Object> map;
//是所有写入 map 的 value 值。
private static final Object PRESENT = new Object();
public HashSet() {
map = new HashMap<>();
}
public HashSet(int initialCapacity, float loadFactor) {
map = new HashMap<>(initialCapacity, loadFactor);
}
public HashSet(int initialCapacity) {
map = new HashMap<>(initialCapacity);
}
public Iterator<E> iterator() {
return map.keySet().iterator();
}
public int size() {
return map.size();
}
//PRESENT是所有写入 map 的 value 值。
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
//...
}
偷偷告诉你,HashSet
中没有 get
方法。
比较关键的就是这个add()
方法。 可以看出它是将存放的对象当做了 HashMap
的健,value
都是相同的 PRESENT
。由于 HashMap
的 key
是不能重复的,所以每当有重复的值写入到HashSet
时,value
会被覆盖,但 key
不会受到影响,这样就保证了HashSet
中只能存放不重复的元素。
这里又要多问一句了,为什么HashMap
的键值是不重复的呢?因为在HashMap
的源码中,是使用key
的hashCode
和key
值去 取值的,hashCode总不能重复吧。这就有源有头了!
public V get(Object key) {
Node<K,V> e;
return (e = getNode(hash(key), key)) == null ? null : e.value;
}
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
ps: 文末推荐其他几篇有关集合的文章:
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/16023.html