2.5 Set接口(HashSet源码解析)

2.5 Set接口的继承关系

2.5 Set接口(HashSet源码解析)_第1张图片
可以看到Set接口和List接口一样的继承关系都是Iterable=>Collection=>Set

2.5.1 Set接口中的方法

java中的Set接口和Colletion是完全一样的定义。

package java.util;
public interface Set<E> extends Collection<E> {
     
    // Query Operations
    int size();
    boolean isEmpty();
    Object[] toArray();
    <T> T[] toArray(T[] a);
    // Modification Operations
    boolean add(E e);
    boolean remove(Object o);
    boolean containsAll(Collection<?> c);
    boolean addAll(Collection<? extends E> c);
    boolean retainAll(Collection<?> c);
    boolean removeAll(Collection<?> c);
    void clear();
    boolean equals(Object o);
    int hashCode();
	//此处和Collection接口由区别
 	Spliterator<E> spliterator() {
     
        return Spliterators.spliterator(this, Spliterator.DISTINCT);
    }
}

java中Set的定义是一种不含有重复元素的一种集合,而Collection没有这个概念的。

2.5.2 HashSet源码

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
     
    static final long serialVersionUID = -5024744406713321676L;
    private transient HashMap<E,Object> map;
    private static final Object PRESENT = new Object();
    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);
    }
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
     
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }
    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;
    }

    public void clear() {
     
        map.clear();
    }
}

可以看到HashSet内部其实是一个HashMap。

2.5.3 HashSet是如何保证不重复的呢?

看HashSet的add方法,插入的值会作为HashMap的key,所以是HashMap保证了不重复。map的put方法新增一个原来不存在的值会返回null,如果原来存在的话会返回原来存在的值。

关于HashMap是如何实现的,见后续!

你可能感兴趣的:(Java,#,2,集合篇,java,HashSet源码解析,HashSet如何保证不重复)