zoukankan      html  css  js  c++  java
  • Java源码初学_HashSet&LinkedHashSet

    一.概述

      HashSet是建立在HashMap的基础上的,其内部存在指向一个HashMap对象的引用,操作HashSet实际上就是操作HashMap,而HashMap中所有键的值都指向一个叫做Dummy value的值.这是一个Object对象.是在HashSet进行显示初始化的时候初始化出来的,而HashMap在构造函数中被创建出来.
    二.HashMap在HashSet方法中的使用及LinkedHashMap
      HashSet是建立在HashMap的基础上的,它的几乎所有的操作都是通过HashMap完成对于key的操作来实现的,通过add方法可以得知,这个HashMap所有的键都指向一个值.

    public class HashSet<E>
        extends AbstractSet<E>
        implements Set<E>, Cloneable, java.io.Serializable
    {
        static final long serialVersionUID = -5024744406713321676L;
        //存储键值对的Map.这个Map将不会被序列化
        private transient HashMap<E,Object> map;
    
        // Dummy value 
        private static final Object PRESENT = new Object();
    
        public HashSet() {
        map = new HashMap<E,Object>();
        }
    
        public HashSet(Collection<? extends E> c) {
        map = new HashMap<E,Object>(Math.max((int) (c.size()/.75f) + 1, 16));
        addAll(c);
        }
    
        public HashSet(int initialCapacity, float loadFactor) {
        map = new HashMap<E,Object>(initialCapacity, loadFactor);
        }
    
        public HashSet(int initialCapacity) {
        map = new HashMap<E,Object>(initialCapacity);
        }
        //LinkedHashSet的实现关键
        HashSet(int initialCapacity, float loadFactor, boolean dummy) {
        map = new LinkedHashMap<E,Object>(initialCapacity, loadFactor);
        }
    
        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);
        }
    
        public boolean add(E e) {
        //放入元素和present的键值对
        return map.put(e, PRESENT)==null;
        }
    
        public boolean remove(Object o) {
        return map.remove(o)==PRESENT;
        }
    
        public void clear() {
        map.clear();
        }

       有两点需要注意的,第一点,这个Map是不会序列化的,因此在写入文件的时候,除了写入文件HashSet的信息以外,还写入map的容量(capacity),装填因子(loadFactor)以及元素数目(size),然后在从文件读取的时候,先创建map,然后依次从map中装填key的信息.代码如下:

    private void writeObject(java.io.ObjectOutputStream s)
            throws java.io.IOException {
        s.defaultWriteObject();
    
            s.writeInt(map.capacity());
            s.writeFloat(map.loadFactor());
    
            s.writeInt(map.size());
    
        for (Iterator i=map.keySet().iterator(); i.hasNext(); )
                s.writeObject(i.next());
        }
    
        private void readObject(java.io.ObjectInputStream s)
            throws java.io.IOException, ClassNotFoundException {
        s.defaultReadObject();
    
            int capacity = s.readInt();
            float loadFactor = s.readFloat();
            map = (((HashSet)this) instanceof LinkedHashSet ?
                   new LinkedHashMap<E,Object>(capacity, loadFactor) :
                   new HashMap<E,Object>(capacity, loadFactor));
    
            int size = s.readInt();
    
        for (int i=0; i<size; i++) {
                E e = (E) s.readObject();
                map.put(e, PRESENT);
            }
        }

        第二点,HashSet中有一个不是公共的有boolean类型的参数的构造方法,它供LinkedHashSet调用.可以将LinkedHashSet内置的Map引用初始化为LinkedHashMap对象.(注意LinkedHashSet无法实现按照访问顺序排序).

  • 相关阅读:
    BZOJ 3132: 上帝造题的七分钟 树状数组+差分
    PAT Advanced 1006 Sign In and Sign Out (25 分)
    PAT Advanced 1011 World Cup Betting (20 分)
    PAT Basic 1032 挖掘机技术哪家强 (20 分)
    PAT Basic 1028 人口普查 (20 分)
    PAT Basic 1004 成绩排名 (20 分)
    大数据数据库HBase(二)——搭建与JavaAPI
    PAT Advanced 1009 Product of Polynomials (25 分)(vector删除元素用的是erase)
    PAT Advanced 1002 A+B for Polynomials (25 分)(隐藏条件,多项式的系数不能为0)
    PAT Basic 1041 考试座位号 (15 分)
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5924833.html
Copyright © 2011-2022 走看看