zoukankan      html  css  js  c++  java
  • HashSet源码分析 jdk1.6

    Set的特点:Set元素无顺序,且元素不可以重复。

    1、定义

    public class HashSet<E>
    extends AbstractSet<E>
    implements Set<E>, Cloneable, java.io.Serializable

     Set接口定义:

    public interface Set<E> extends Collection<E> {
        // Query Operations
        int size();
        boolean isEmpty();
        boolean contains(Object o);
        Iterator<E> iterator();
        Object[] toArray();
        <T> T[] toArray(T[] a);
        // Modification Operations
        boolean add(E e);
        boolean remove(Object o);
        // Bulk Operations
        boolean containsAll(Collection<?> c);
        boolean addAll(Collection<? extends E> c);
        boolean retainAll(Collection<?> c);
        boolean removeAll(Collection<?> c);
        void clear();
        // Comparison and hashing
        boolean equals(Object o);
        int hashCode();
    }

    2、底层存储

    // 底层使用HashMap来保存HashSet的元素
        private transient HashMap<E,Object> map;
    
        // Dummy value to associate with an Object in the backing Map
        // 由于Set只使用到了HashMap的key,所以此处定义一个静态的常量Object类,来充当HashMap的value
        //用于避免java.lang.NullPointerException异常
    private static final Object PRESENT = new Object();

    3、构造方法

    /**
         * 使用HashMap的默认容量大小16和默认加载因子0.75初始化map,构造一个HashSet
         */
        public HashSet() {
            map = new HashMap<E,Object>();
        }
    
        /**
         * 构造一个指定Collection参数的HashSet,这里不仅仅是Set,只要实现Collection接口的容器都可以
         */
        public HashSet(Collection<? extends E> c) {
            map = new HashMap<E,Object>(Math. max((int) (c.size()/.75f) + 1, 16));
           // 使用Collection实现的Iterator迭代器,将集合c的元素一个个加入HashSet中
           addAll(c);
        }
    
        /**
         * 使用指定的初始容量大小和加载因子初始化map,构造一个HashSet
         */
        public HashSet( int initialCapacity, float loadFactor) {
            map = new HashMap<E,Object>(initialCapacity, loadFactor);
        }
    
        /**
         * 使用指定的初始容量大小和默认的加载因子0.75初始化map,构造一个HashSet
         */
        public HashSet( int initialCapacity) {
            map = new HashMap<E,Object>(initialCapacity);
        }
    
        /**
         * 不对外公开的一个构造方法(默认default修饰),底层构造的是LinkedHashMap,dummy只是一个标示参数,无具体意义
         */
        HashSet( int initialCapacity, float loadFactor, boolean dummy) {
            map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
    }

    4、增加和删除

    /**
         * 利用HashMap的put方法实现add方法
         */
        public boolean add(E e) {
            return map .put(e, PRESENT)== null;
        }
    
        /**
         * 利用HashMap的remove方法实现remove方法
         */
        public boolean remove(Object o) {
            return map .remove(o)==PRESENT;
        }
    
        /**
         * 添加一个集合到HashSet中,该方法在AbstractCollection中
         */
        public boolean addAll(Collection<? extends E> c) {
            boolean modified = false;
           // 取得集合c迭代器Iterator
           Iterator<? extends E> e = c.iterator();
           // 遍历迭代器
            while (e.hasNext()) {
               // 将集合c的每个元素加入到HashSet中
               if (add(e.next()))
                  modified = true;
           }
            return modified;
        }
        
        /**
         * 删除指定集合c中的所有元素,该方法在AbstractSet中
         */
        public boolean removeAll(Collection<?> c) {
            boolean modified = false;
    
            // 判断当前HashSet元素个数和指定集合c的元素个数,目的是减少遍历次数
            if (size() > c.size()) {
                // 如果当前HashSet元素多,则遍历集合c,将集合c中的元素一个个删除
                for (Iterator<?> i = c.iterator(); i.hasNext(); )
                    modified |= remove(i.next());
            } else {
                // 如果集合c元素多,则遍历当前HashSet,将集合c中包含的元素一个个删除
                for (Iterator<?> i = iterator(); i.hasNext(); ) {
                    if (c.contains(i.next())) {
                        i.remove();
                        modified = true;
                    }
                }
            }
            return modified;
    }

    Hashset的很多地方就是利用 hashmap的key实现的

  • 相关阅读:
    div定位
    学习进度条(第十周)
    学习进度条(第九周)
    软件工程个人作业--找水王
    个人NABCD
    梦断代码阅读笔记01---死定了
    进度条(第八周)
    学习进度条(第七周)
    软件工程结对开发作业02---二维数组求最大连通子数组
    软件工程结对作业01--四则运算Web版
  • 原文地址:https://www.cnblogs.com/L-a-u-r-a/p/8540828.html
Copyright © 2011-2022 走看看