JDK7--HashMap源码分析(二)

一.遍历

    遍历的方法:

  • keySet()。
  • entrySet()。

    从代码来看,entrySet的遍历方式要比keySet的遍历方式少了一次根据Key查找Value操作,应该更加高效一些。

HashMap 中的modCount属性,表示的是该hashMap被修改的次数,此属性主要是在遍历功能里面使用。

modCount属性与ConcurrentModificationException 异常有关。

    迭代器的modCount和expectedModCount的值不一致。

    单线程中该异常出现的原因是:对一个集合遍历的同时,有对该集合进行了增删的操作。导致HashMap的modCount和expectedModCount的值不一致。

    多线程中更容易出现该异常,当你在一个线程中对一数据集合进行遍历,正赶上另外一个线程对该数据集合进行增删操作。



二.序列化

    HashMap实现了Serializable接口,表示它能够被序列化。但是存储数据的table变量前面加上了transient关键字,这个关键字的意思是在序列化的时候不用管这个变量。那究竟是为什么呢?因为不同的JVM针对对同一个对象产生的hashcode值不同,导致在不同JVM反序列化时会可能会得到不同的对象。

    而HashMap自己实现了writeObject(ObjectOutputStream)和readObject(ObjectInputStream)这两个方法。看到网上有人说在实现序列化的时候,如果该类实现了writeObject和readObject这两个方法那么就会调用该类的实现,如果没有的话就会使用defaultWriteObject()和defaultReadObject(),而HashMap就是自己实现了writeObject和readObject方法,自己对table做了处理。

private void writeObject(java.io.ObjectOutputStream s)
        throws IOException
    {
        Iterator<Map.Entry<K,V>> i =
            (size > 0) ? entrySet0().iterator() : null;

        // Write out the threshold, loadfactor, and any hidden stuff
        s.defaultWriteObject();

        // Write out number of buckets
        s.writeInt(table.length);

        // Write out size (number of Mappings)
        s.writeInt(size);

        // Write out keys and values (alternating)
        if (i != null) {
            while (i.hasNext()) {
                Map.Entry<K,V> e = i.next();
                s.writeObject(e.getKey());
                s.writeObject(e.getValue());
            }
        }
    }
private void readObject(java.io.ObjectInputStream s)
         throws IOException, ClassNotFoundException
    {
        // Read in the threshold, loadfactor, and any hidden stuff
        s.defaultReadObject();

        // Read in number of buckets and allocate the bucket array;
        int numBuckets = s.readInt();
        table = new Entry[numBuckets];

        init();  // Give subclass a chance to do its thing.

        // Read in size (number of Mappings)
        int size = s.readInt();

        // Read the keys and values, and put the mappings in the HashMap
        for (int i=0; i<size; i++) {
            K key = (K) s.readObject();
            V value = (V) s.readObject();
            putForCreate(key, value);
        }
    }



发布了9 篇原创文章 · 获赞 0 · 访问量 7073

猜你喜欢

转载自blog.csdn.net/yangyingjieshiwo/article/details/80555311
今日推荐