数据结构 - HashSetLinkedHashSet 二合一

Posted yuanjiangnan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构 - HashSetLinkedHashSet 二合一相关的知识,希望对你有一定的参考价值。

技术图片

简介

HashSet 是HashMap键的封装,我们都知道HashMap是数组+链表或数组+树结构,那么HashSet也是这种结构。HashMap只能存入一个null键,那么HashSet也就只能有一个null值;LinkedHashSet 是LinkedHashMap 键的封装,LinkedHashSet 继承HashSet。

HashSet 类
public class HashSet<E> extends AbstractSet<E>
        implements Set<E>, Cloneable, java.io.Serializable

跟ArraryList相比没有实现RandomAccess接口,接下来看成员变量和构造函数

HashSet 属性
// 底层是HashMap实现的   
private transient HashMap<E,Object> map;
// PRESENT是一个假的value值,帮助用HashMap实现HashSet。
private static final Object PRESENT = new Object();
HashSet 构造函数
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);
}
public HashSet(Collection<? extends E> c) {
    map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
    addAll(c);
}

通过构造函数可以看出HashSet的初始化时内部构建了一个HashMap对象

HashSet(int initialCapacity, float loadFactor, boolean dummy) {
    map = new LinkedHashMap<>(initialCapacity, loadFactor);
}

此构造函数安全级别为默认,只有自己或同包子类可以调用。HashSet并没有调用它,它是给子类使用的,跟上面构造函数唯一的区别就是内部Map换成LinkedHashMap<>对象

HashSet 方法
// 获取长度
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) {
    // 添加元素时,元素为键,值为固定常量存入Map
    return map.put(e, PRESENT)==null;
}
// 删除元素
public boolean remove(Object o) {
    return map.remove(o)==PRESENT;
}
// 清空
public void clear() {
    map.clear();
}

发现了什么?HashSet只是用了HashMap的key,而值是一个固定的常量,所以HashMap的key拥有哪些特性HashSet就拥有哪些特性。
关于HashSet,推荐先看HashMap篇,看完之后才能完全理解HashSet

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

LinkedHashSet完成继承HashSet,内部只有构造函数

LinkedHashSet 构造函数
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);
}

LinkedHashSet 所有构造函数都调用HashSet的HashSet(int initialCapacity, float loadFactor, boolean dummy)构造函数,内部使用LinkedHashMap对象
技术图片



以上是关于数据结构 - HashSetLinkedHashSet 二合一的主要内容,如果未能解决你的问题,请参考以下文章

在数据结构中数据、数据元素、数据对象、数据结构、存储结构、数据类型以及抽象数据类型的定义分别是啥

数据结构与数据类型有啥区别?

数据结构都有哪些

数据结构和数据类型的区别

数据结构哪些是四种常见的逻辑结构

数据结构基本概念