无序,不允许存放重复的元素;
实现类:
源码分析
属性
private transient HashMap<E,Object> map;
private static final Object PRESENT = new Object();
定义一个 HashMap 作为数据存储,
定义一个虚拟的 Object 对象 PRESENT作为 HashMap 的 value 。
构造器
public HashSet() {
map = new HashMap<>();
}
public HashSet(Collection<? extends E> c) {
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);
}
//此构造器是LinkedHashSet实例化调用
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
可以看到HashSet的构造器就是new了一个HashMap。
方法
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);}
public boolean add(E e) {
return map.put(e, PRESENT)==null;}
public boolean remove(Object o) {
return map.remove(o)==PRESENT;}
可以看到HashSet的绝大部分方法都是通过调用HashMap 的方法来实现的,因此HashSet 和HashMap 两个集合在实现本质上是相同的。区别在于HashSet只存放一个key,而HashMap存放的是键值对。
想了解HashMap的小伙伴请点击链接HashMap源码分析
基于LinkedHashMap实现。用LinkedHashMap作为数据存储,保证了元素迭代的顺序,即插入顺序。继承 HashSet,其内部只定义spliterator()方法。可以直接调用父类HashSet的方法。
LinkedHashSet继承HashSet
public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable {
构造器
public LinkedHashSet(int initialCapacity, float loadFactor) {
super(initialCapacity, loadFactor, true);
}
public LinkedHashSet(int initialCapacity) {
super(initialCapacity, .75f, true);
}
public LinkedHashSet() {
super(16, .75f, true);
}
public LinkedHashSet(Collection<? extends E> c) {
super(Math.max(2*c.size(), 11), .75f, true);
addAll(c);
}
HashSet(int initialCapacity, float loadFactor, boolean dummy) {
map = new LinkedHashMap<>(initialCapacity, loadFactor);
}
可以看到LinkedHashSet的构造器都调用了父类HashSet的HashSet(int initialCapacity, float loadFactor, boolean dummy)构造器new了一个LinkedHashMap。因此LinkedHashSet 和LinkedHashMap 两个集合在实现本质上是相同的。但new LinkedHashMap时,并没有设置accessOrder,所以LinkedHashSet只能实现插入顺序,不能实现访问顺序。(这个不太确定,如结论有误,评论区期待大佬指正!!!)
想了解LinkedHashMap的小伙伴请点击链接LinkedHashMap源码分析
基于TreeMap实现,应用方法都一样;值都为new Object();