• 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无法实现按照访问顺序排序).

  • 相关阅读:
    Nginx入门
    Spring基础知识汇总 Java开发必看
    java ArrayList倒序
    1
    js event 的target 和currentTarget
    java 文件的写入和读取
    DOMContentLoaded与load的区别
    JS中先有Object还是先有Function?
    JSON.stringify的三个参数
    Java的泛型约束和限制
  • 原文地址:https://www.cnblogs.com/hlhdidi/p/5924833.html
Copyright © 2020-2023  润新知