HashSet

本文深入解析了HashSet与HashMap的工作原理及使用方式,包括数据结构、常用方法等,并对比了它们的特点,如有序性、存储方式及性能差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Base:JDK1.8

1、HashSet

前面说完了HashMap,说HashSet就很好说了,因为HashSet也是一个 哈希表组成的,更直接的说,它的底层是直接使用了 HashMap 做的。

HashSet 内容挺少的。

所以在这个上面就不写那么多了,重要的 都在HashMap 里面,不过作为两者的区别 ,还是要说的。

2、继承的类和实现的接口

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

 可以看出, HashSet 是 实现了set 接口,那么看下set 接口:

public interface Set<E> extends Collection<E> 

set接口 则是继承 Collection 接口的,因此它 是跟 List  是兄弟,跟Map 没啥关系,都是集合。

不过要知道的是 List  是一个 有序的 集合,而HashSet 是一个无序的集合。

在这里 要知道, 有序 无序,并不是指的 排序,而是指的  存入顺序,有一个存入先后的 概念,而set 是没有的。

上面都是基于数据结构说的,HashMap也是无序的。

因此,在HashSet中是没有 get() 这种方法的。

3、HashMap中的成员变量、数据结构、常用方法

3.1 成员变量

private transient HashMap<E,Object> map;

你看,底层数组直接使用的就是 HashMap。。。

大家注意第二个是Object,第一个是泛型

// Dummy value to associate with an Object in the backing Map
    private static final Object PRESENT = new Object();

这是一个 final 修饰的 Object 的常量。  我们都知道,HashMap 是基于 K-V形式

而 set 存的时候只放入一个 value ,那剩余的一个怎么办呢? 其实就是直接使用的这个常量代替的。

当然  我说的value  意思是  你把你存储的 东西当做是一个 value ,而在底层 ,则是将你存入的数据作为 Key值,而这个常量 Object 作为一个Value 存起来。

这个后面会用代码展现。

3.2 数据结构

private transient HashMap<E,Object> map;

这就很明显了, 是HashMap 的 数据结构。

3.3 常用方法

3.3.1 构造方法

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

这几个构造方法直接全放一起吧,很简单。

3.3.2 add

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

这段代码 很自然的显示出了, put的时候, 你存入的数据作为一个key 值存入,而那个常量则作为一个 value 值存入。

这就造成了,set 不能存重复的东西,因为 HashMap 的 key 值是不能重复的。

3.3.3 get

当然,是没有get方法的。哈哈哈

3.3.4 remove

 public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
    }

 

微总结:

ArrayList、LinkedList、HashSet 是都是来自Collection 的子类, 而HashMap 则是Map 的子类

因此这是需要主意的一点

ArrayList、LinkedList 是两个有序的,这 有序是 可以保存 存入时候的顺序,即在 不适用 add(v,index),表明插入下表的话,顺序就是保存的顺序,

而HashSet 、HashMap 则不在意 存入的顺序,因为会进行hash 算法,求取一个 index 放入到 哈希表中

而HashSet 又跟HashMap 正好有点相反的意思,虽然 HashSet 是基于HashMap 但是一个 HashSet 是把你存入的数据当做一个 key 存进去, HashMap则是 把存入的数据作为 value 存入。

HashMap 是 key值 不能相同  因此决定了 HashSet  不能存重复的值。

HashMap 计算的 哈希值 是你存入的 key 的哈希值,而HashSet  则是 使用的你 传入的 数据 计算的Hash值的,其实都是使用的key啦。。。。

ArrayList 跟 LinkedList 的性能有点一边倒。一个注重查询,一个注重插入,删除,当然: 数据量大。。。

如果你都是插入到最后,查询的都是 第一个,几乎是没有差距。。

HashSet 跟HashMap 两者都不能重复。第一个是 你存的数据不能是重复的, 第二个是 你存入的 key 值是不能重复。

HashMap 更重要,而且 据我现在的了解,貌似 key-value 形式 非常非常非常的常见,而且重要,用到的地方非常多。

 

-----------------------------------------------------------------------------

不保证代码完全正确,也不保证代码是最优。

仅仅是根据自己的理解,写出来直观的代码,方便理解。

错误请指出,感激不尽!

转载于:https://my.oschina.net/u/3192601/blog/1525818

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值