HashSet从入门到入土

    技术2023-06-14  83

    HashSet从入门到入土

    Hashset是什么

    ​ 下面就是HashSet的继承关系图

    HashSet内部使用的是HashMap

    ​ 当我们去看HashSet的构造方法的时候我们会发现直接new了一个HashMap,并且赋给了map属性。

    ​ 即HashSet就是在HashMap上面套了个壳,方法也比较简单,每个方法其实都是对应的操作map。

    HashSet如何去重的

    ​ 因为HashSet是继承了Set,所以就不能有重复项。我们大多数情况下使用HashSet也是因为它有去重的功能。

    ​ 要实现去重,HashSet从add方法就开始了

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

    从这里我们可以看出,HashSet的add方法调用了HashMap的put方法,但是put进去的是一个键值对,而HashSet存的不是键值对,是一个泛型。

    ​ 所以说HashSet把你要存放的值当做key,而对应的value是一个final的Object对象,只起到一个占位作用。这个时候由于HashMap不允许key重复所以正好被HashSet拿来使用用来保证其不重复。

    非线程安全的

    ​ 由于HashMap不是线程安全的,所以HashSet也不是线程安全的,所以在多线程,高并发的情况下慎用。

    ​ 而且HashSet没有像Hashmap那样的多线程版本,如果想用多线程模式就使用如下的:

    Set<String> set = Collections.synchronizedSet(new HashSet<String>());

    或者使用ConcurrentHashMap的一个实现了Set接口的静态内部类。

    LinkedHashSet

    ​ 类似的LinkedHashSet也是一个套壳的LinkedHashMap,对比HashSet它的特点就是保证数据有序,插入的时候是什么顺序,遍历的时候就是什么顺序

    无参构造函数

    public LinkedHashSet() { super(16, .75f, true); }

    由于LinkHashSet继承自HashSet所以其实是调用了HashSet的三个参数的构造函数

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

    这次不是new一个HashMap了而是new了一个LinkedHashMap,这就是它能保证有序的关键,LinkedHashMap用双向连败OA的方式在HashMap的基础上额外保存了键值对的插入顺序

    ​ 由于LinkedHashMap可以保证键值对的顺序所以用来实现简单的LRU缓存。

    ​ 所以当你既要保证元素无重复,又要保证元素有序,可以使用LinkedHashSet

    最后

    如果觉得看完有收获,希望能给我点个赞,这将会是我更新的最大动力,感谢各位的支持欢迎各位关注我的公众号【java冢狐】,专注于java和计算机基础知识,保证让你看完有所收获,不信你打我如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。

    Processed: 0.019, SQL: 9