Java中的HashSet

HashSet是一种存储不可重复元素的集合,元素在集合中是无序的(元素不是按照添加顺序存储)。

特点

  1. 元素不可重复:依据hash值和元素内容进行判断,若添加的元素与已有元素重复,则不会添加
  2. 元素是无序的:元素存放位置是根据hash值随机分布的
  3. 允许null值:集合中允许存放null值
  4. 非线程安全:没有多线程操作支持,若需要支持线程安全,可使用Collections.synchronizedSet()或其他并发容器

设计原理

  • HashSet底层数据结构是基于HashMap实现的,具有HashMap的所有特点(数据结构是素组+链表+红黑树)
  • HashSet中的HashMap实际只在key存储真实元素,value值是一个固定的常量
  • HashSet中的HashMap默认初始化容量为16,当元素数量达到容量的75%时,数组会扩容到原来的2倍
  • HashSet中的HashMap,链表长度达到8并且数组长度达到64,链表会进行树化
  • HashSet在首次添加元素时进行初始化,减少内存占用
  • HashSet的实现是基于适配器模式(通过包装HashMap的接口,适配成Set接口的方式)

方法

构造方法
public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable
{
    static final long serialVersionUID = -5024744406713321676L;

    //存储元素的map
    private transient HashMap<E,Object> map;

    //map中value存放的元素(是一个常量)
    private static final Object PRESENT = new Object();

    //创建一个空的HashSet
    public HashSet() {
        map = new HashMap<>();
    }

    //创建一个新的map,将传入的Collection集合元素放入map中
    public HashSet(Collection<? extends E> c) {
        map = new HashMap<>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
    }

    //指定初始化容量和扩容因子的map集合
    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);
    }
}
添加单个元素
    //实际调用HashMap中的put方法,key是实际元素,value是一个常量
    public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
删除元素
    //删除某一个元素
    public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }
添加多个元素
    //使用的是抽象类AbstractCollection中的方法,循环体中的add(e)是HashSet自行实现的
    public boolean addAll(Collection<? extends E> c) {
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }
是否包含某个元素
    //实际调用HashMap的containsKey方法
    public boolean contains(Object o) {
        return map.containsKey(o);
    }
迭代器
    //调用的是HashMap中的keyset迭代器
    public Iterator<E> iterator() {
        return map.keySet().iterator();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值