Java集合——HashSet

169 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路

Java集合——HashSet

HashSet

基于HashCode计算元素存放位置。 当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入。

HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。

HashSet 允许有 null 值。

HashSet 是无序的,即不会记录插入的顺序。

HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。

HashSet 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。

HashSet 实现了 Set 接口 在这里插入图片描述

关于重写hashCode

public int hashCode(){
	final int prime = 31;
	int res = 1;
	res = prime * res + ((属性==null)?0:属性.hashCode());
	return res;
}

HashSet如何存储元素

HashSet的存储结构:哈希表(数组+链表+红黑树)

1.根据hashcode计算保存位置

如果此位置为空则直接保存,如果不为空则继续

2.执行equals方法

若返回值为true,则认为是重复的,否则形成链表

源码解读

HashSet如何添加元素

参照我写的HashMap添加元素:blog.csdn.net/qq_51553982…

public boolean add(E e) {
        return map.put(e, PRESENT)==null;
    }
public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
    }

 final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
                   boolean evict) {
        Node<K,V>[] tab; Node<K,V> p; int n, i;
        if ((tab = table) == null || (n = tab.length) == 0)
            n = (tab = resize()).length;
        if ((p = tab[i = (n - 1) & hash]) == null)
            tab[i] = newNode(hash, key, value, null);
        else {
            Node<K,V> e; K k;
            if (p.hash == hash &&
                ((k = p.key) == key || (key != null && key.equals(k))))
                e = p;
            else if (p instanceof TreeNode)
                e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
            else {
                for (int binCount = 0; ; ++binCount) {
                    if ((e = p.next) == null) {
                        p.next = newNode(hash, key, value, null);
                        if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st
                            treeifyBin(tab, hash);
                        break;
                    }
                    if (e.hash == hash &&
                        ((k = e.key) == key || (key != null && key.equals(k))))
                        break;
                    p = e;
                }
            }
            if (e != null) { // existing mapping for key
                V oldValue = e.value;
                if (!onlyIfAbsent || oldValue == null)
                    e.value = value;
                afterNodeAccess(e);
                return oldValue;
            }
        }
        ++modCount;
        if (++size > threshold)
            resize();
        afterNodeInsertion(evict);
        return null;
    }