HashSet从入门到入土

HashSet从入门到入土

Hashset是什么

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bMUfHjgu-1593755190238)(https://raw.githubusercontent.com/iszhonghu/Picture-bed/master/img/20200702171047.png)]

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和计算机基础知识,保证让你看完有所收获,不信你打我
  • 如果看完有不同的意见或者建议,欢迎多多评论一起交流。感谢各位的支持以及厚爱。

猜你喜欢

转载自blog.csdn.net/issunmingzhi/article/details/107104219