java (Hash)Set和(Hash)Map的关系

这篇未完,待续写

总述:

放一张Map,Set关系图,TreeSet使用TreeMap,HashSet使用HashMap(主要)和LinkedHashMap,LinkedHashSet继承自HashSet,调用了(HashSet中调用的LinkedHashMap).

HashSet底层是HashMap实现的,因为Set元素不能重复和Map的key也不能重复,所以Set是使用了Map的一部分功能(key的那一部分),

这是HashSet源码的一部分,简单介绍下,源码基于jdk11

public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;
//定义一个HashMap类型的变量map
    private transient HashMap<E,Object> map; 
//定义常量PRESENT为一个new Object对象
    private static final Object PRESENT = new Object();
    public HashSet() {
        //无参构造方法,创建一个HashMap对象,返回
        map = new HashMap<>();
    }
    public HashSet(Collection<? extends E> c) {
    //创建一个HashMap对象
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }
    public HashSet(int initialCapacity) {
        map = new HashMap<>(initialCapacity);
    }

   //当构造方法的参数为初始容量,负载因子,还有dummy不晓得,这三个参数时,返回LinkedHashMap对象
    HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<>(initialCapacity, loadFactor);
    }

...
}

HashSet的add()方法:

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

调用Map接口(这里是HashMap对象)的put方法,key是咱们添加到HashSet中的元素,value是之前定义的new Object

所以添加对象的时候先计算hashCode值是否存在于hash数组表中,如果不存在,在索引位置处创建,如果存在,调用equals方法比较两个元素是否相同,相同,则不存放,不相同存放到链表中

...................

LinkedHashSet跟LinkedHashMap的关系:

LinkedHashSet继承自HashSet,构造方法直接调用父类的有三个参数的构造方法,返回LinkedHashMap对象

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

    private static final long serialVersionUID = -2851667679971038690L;

    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);
    }

TreeSet和TreeMap的关系:

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    
    private transient NavigableMap<E,Object> m;
    private static final Object PRESENT = new Object();
    TreeSet(NavigableMap<E,Object> m) {
        this.m = m;
    }
    public TreeSet() {
        this(new TreeMap<>());
    }
//传入参数为Comparator的子类或者实例
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
    public TreeSet(Collection<? extends E> c) {
        this();
        addAll(c);
    }
    public TreeSet(SortedSet<E> s) {
        this(s.comparator());
        addAll(s);
    }
...
}

TreeSet的构造方法,返回的是TreeMap对象

参考:https://www.cnblogs.com/skywang12345/p/3311252.html

        https://blog.csdn.net/riverflowrand/article/details/55520145

猜你喜欢

转载自blog.csdn.net/sinat_41132860/article/details/84302649
今日推荐