zoukankan      html  css  js  c++  java
  • Set集合是如何保证元素不重复的?

          我们都知道Set容器中的元素是无序不重复的,那么Set集合是怎么保证元素不重复的呢?Set是一个接口,

    HashSet是Set接口的具体实现,以HashSet为例,来看一下它的具体实现。

         先来看一下HashSet源码中的的几个构造器:

    private transient HashMap<E,Object> map;
    
        private static final Object PRESENT = new Object();//注意这个变量,待会会用到
      

      //这个是经常使用到的构造器,可以发现无论是哪一个构造器,HashSet的底层实现都是创建了一个HashMap 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的add方法的源码:

    public boolean add(E e) {
         //PRESENT是一个虚拟值,是为了HashMap实现HashSet的一个假设的值
    return map.put(e, PRESENT)==null; }

      当HashSet进行add操作时,其实是将要add的元素作为map的key,将PRESENT这个对象作为map的value,存入map中,并且需要注意到add方法的返回值是一个boolean。

          其实到这里,我们应该能明白为什么HashSet中的元素不能重复了:

                      因为HashSet的底层是由HashMap实现的,而HashSet的add方法,是将元素作为map的key进行存储的,map的key是不会重复的,所以HashSet中的元素也不会重复。

     接下来看个例子:

    public static void main(String[] args) {
            Set<Object> set = new HashSet<Object>();
            boolean b1 = set.add(2018);
            boolean b2 = set.add("Hello");
            boolean b3 = set.add(2018);
            System.out.println(b1);//true
            System.out.println(b2);//true
            System.out.println(b3);//false
        }

    输出一下,结果是:

    true
    true
    false

    也就是说,(结合HashSet的add方法源码)当add相同元素的时候,map.put(e, PRESENT) != null ,再来看一下一个map的例子:

    public static void main(String[] args) {
            Map<Object, Object> map = new HashMap<Object, Object>();
            Object o1 = map.put(2018, 11111);
            Object o2 = map.put("Hello", "world");
            Object o3 = map.put(2018, 22222);
            System.out.println(o1);
            System.out.println(o2);
            System.out.println(o3);
        }

    输出:

    null
    null
    11111

    可以发现,当map存入相同的key的时候,返回值是上一个value,这就使得set在add相同元素的时候,map.put(e, PRESENT) != null,

    导致set在执行add方法的时返回false,add失败。

  • 相关阅读:
    gitlab web端使用
    1、gitlab的理论知识
    git命令
    gitlab web客户端的使用
    jenkins
    jenkins pipeline
    nginx
    ELK(+Redis)-开源实时日志分析平台
    OpenStack构架知识梳理
    Linux 下的dd命令使用详解
  • 原文地址:https://www.cnblogs.com/mianduijifengba/p/10461865.html
Copyright © 2011-2022 走看看