Set总结

时间:2018-12-22
本文章向大家介绍Set总结,主要包括Set总结使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

     Set(保证唯一)
     无序,唯一(不可重复)


     HashSet的底层实现

 public HashSet() {
        map = new HashMap<E,Object>();
    }
     public V put(K key, V value) {
     //判断对象是否为Null
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
            Object k;
            //比较hash值、地址值和内容
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }

        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }


     为啥存储字符串的时候,字符串内容相同的只存储一个。  --就是hashCode()和equals()方法
     通过查看add方法的源码,我们知道这个方法的底层依赖两个方法 hashCode()和equals()
     步骤:
         先看hashCode()值是否相同
             相同:继续走equals()方法
                 返回true:说明元素重复,不添加
                 返回false:说明元素不重复,则添加到集合中去
             不同:就直接把元素添加到集合中去
         如果类没有重写这两个方法,默认使用Object()。一般来说不相同。因为之比较地址值
         而String类重写了hashCode()和equals()方法,所以他就可以把相同的字符串去掉,之保留其中一个


     LinnkedHashSet集合
         底层数据结构是hash表和链表
         哈希表保证元素唯一
         链表保证元素有序。(存储和取出顺序一致) 


     TreeSet集合    
         排序、唯一
         A:底层数据结构是红黑树(是一个自平衡的二叉树)    
         B:保证元素的排序和唯一(运用二叉排序树)
             a:自然排序:(元素具备比较性)    
                 让元素所属的类实现Comparable接口
             b:比较器排序(集合具备比较性)
                 让集合的构造方法接受comparator的实现类对象
                     
       

   public V put(K key, V value) {
        Entry<K,V> t = root;
        if (t == null) {
        // TBD:
        // 5045147: (coll) Adding null to an empty TreeSet should
        // throw NullPointerException
        //
        // compare(key, key); // type check
            root = new Entry<K,V>(key, value, null);
            size = 1;
            modCount++;
            return null;
        }
        int cmp;
        Entry<K,V> parent;
        // split comparator and comparable paths
        Comparator<? super K> cpr = comparator;
        if (cpr != null) {
            do {
                parent = t;
                cmp = cpr.compare(key, t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        else {
            if (key == null)
                throw new NullPointerException();
            Comparable<? super K> k = (Comparable<? super K>) key;
            do {
                parent = t;
                cmp = k.compareTo(t.key);
                if (cmp < 0)
                    t = t.left;
                else if (cmp > 0)
                    t = t.right;
                else
                    return t.setValue(value);
            } while (t != null);
        }
        Entry<K,V> e = new Entry<K,V>(key, value, parent);
        if (cmp < 0)
            parent.left = e;
        else
            parent.right = e;
        fixAfterInsertion(e);
        size++;
        modCount++;
        return null;
    }