zoukankan      html  css  js  c++  java
  • HashSet 详解

    基本介绍

    1. 不允许重复(底层是HashMap,用key储存元素,value统一都是 PRESENT),可以为null,无顺序
    
    2. HashSet就是为了提高查找效率的(在查找是否存在某个值时,ArrayList需要遍历才能确定某个值的位置,而HashSet可以通过HashCode快速定位)
    

    源码分析

    public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable {
        static final long serialVersionUID = -5024744406713321676L;
    
        //底层是HashMap
        private transient HashMap<E,Object> map;
    
        //定义一个虚拟的Object对象作为HashMap的value,将此对象定义为static final。
        private static final Object PRESENT = new Object();
    
        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);
        }
    
        //底层实际调用底层HashMap的keySet来返回所有的key
        public Iterator<E> iterator() {
            return map.keySet().iterator();
        }
    
        public int size() {
            return map.size();
        }
    
        public boolean isEmpty() {
            return map.isEmpty();
        }
    
        public boolean contains(Object o) {
            return map.containsKey(o);
        }
    
        //如果向HashSet中添加一个已经存在的元素时,新添加的集合元素将不会被放入HashMap中, 
        //原来的元素也不会有任何改变,这也就满足了Set中元素不重复的特性
        public boolean add(E e) {
            return map.put(e, PRESENT)==null;
        }
    
        public boolean remove(Object o) {
            return map.remove(o)==PRESENT;
        }
    
        public void clear() {
            map.clear();
        }
    
    
        @SuppressWarnings("unchecked")
        public Object clone() {
            try {
                HashSet<E> newSet = (HashSet<E>) super.clone();
                newSet.map = (HashMap<E, Object>) map.clone();
                return newSet;
            } catch (CloneNotSupportedException e) {
                throw new InternalError(e);
            }
        }
    
    
        private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
            // Write out any hidden serialization magic
            s.defaultWriteObject();
    
            // Write out HashMap capacity and load factor
            s.writeInt(map.capacity());
            s.writeFloat(map.loadFactor());
    
            // Write out size
            s.writeInt(map.size());
    
            // Write out all elements in the proper order.
            for (E e : map.keySet())
                s.writeObject(e);
        }
    
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
            // Read in any hidden serialization magic
            s.defaultReadObject();
    
            // Read capacity and verify non-negative.
            int capacity = s.readInt();
            if (capacity < 0) {
                throw new InvalidObjectException("Illegal capacity: " +
                                                 capacity);
            }
    
            // Read load factor and verify positive and non NaN.
            float loadFactor = s.readFloat();
            if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
                throw new InvalidObjectException("Illegal load factor: " +
                                                 loadFactor);
            }
    
            // Read size and verify non-negative.
            int size = s.readInt();
            if (size < 0) {
                throw new InvalidObjectException("Illegal size: " +
                                                 size);
            }
    
            // Set the capacity according to the size and load factor ensuring that
            // the HashMap is at least 25% full but clamping to maximum capacity.
            capacity = (int) Math.min(size * Math.min(1 / loadFactor, 4.0f),
                    HashMap.MAXIMUM_CAPACITY);
    
            // Constructing the backing map will lazily create an array when the first element is
            // added, so check it before construction. Call HashMap.tableSizeFor to compute the
            // actual allocation size. Check Map.Entry[].class since it's the nearest public type to
            // what is actually created.
            SharedSecrets.getJavaObjectInputStreamAccess()
                         .checkArray(s, Map.Entry[].class, HashMap.tableSizeFor(capacity));
    
            // Create backing HashMap
            map = (((HashSet<?>)this) instanceof LinkedHashSet ?
                   new LinkedHashMap<>(capacity, loadFactor) :
                   new HashMap<>(capacity, loadFactor));
    
            // Read in all elements in the proper order.
            for (int i=0; i<size; i++) {
                @SuppressWarnings("unchecked")
                    E e = (E) s.readObject();
                map.put(e, PRESENT);
            }
        }
    }
    
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符删除
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
    Java实现 蓝桥杯VIP 算法训练 字符串编辑
  • 原文地址:https://www.cnblogs.com/loveer/p/11533893.html
Copyright © 2011-2022 走看看