zoukankan      html  css  js  c++  java
  • HashMap,LinkedHashMap和Hashtable类的深入剖析与理解

    上一篇文章写了一些关于HashMap以及HashMap的线程安全问题,这篇文章再来说说Map系列中HashMap,LinkedHashMap和Hashtable三者之间的差异以及该注意的地方。

    HashMap的该注意的地方就不赘述了,上一篇已经描写叙述过了。

    一。LinkedHashMap的知识点


    从类名上理解,这个类是个链表HashMap,这个类继承了HashMap,重写了父类的一些方法。关于LinkedHashMap,有下面注意的地方:

    1. LinkedHashMap的初始默认容量为16,加载因子为0.75(继承与HashMap)

    2. LinkedHashMap不支持线程安全

    3. LinkedHashMap同意key和value为null

    4. LinkedHashMap是个双链表,遵循先进先出原则

    二,Hashtable的知识点


    这个类继承了Dictionary类,而且也实现了Map和Cloneable,Serializable接口。也就是说,这个类能够被克隆,也能够被序列化,这个类有下面注意的地方:

    1. Hashtable的初始默认容量为16,加载因子为0.75

    2. Hashtable是线程安全的

    3. Hashtable不同意key或者value为null

    4. Hashtable的操作使用了synchronized来达到线程安全问题,连entrySet()方法中也用了Collections.synchronizedSet(),可是还是避免不了Iterator的高速失败,因此。在有迭代器操作时。一定要注意。


    三,HashMap和LinkedHashMap的关键点


    事实上LinkedHashMap的关键功能就是为了保证插入的数据的顺序问题。

    因为LinkedHashMap是双链表结构。那这样导致每次插入的数据都是由指针顺序指向的。因此取数据时,也就是顺序取了,假设你的结合大多数情况下,在copy时还要保证顺序不变,那么LInkedHashMap是个非常好的选择;而HashMap因为是通过hash来存储在Hash表中的值来查找数据的,而hash值又是随机的,这样导致存入的数据顺序和取出来的数据顺序是不同的,下面各自是LinkedHashMap和HashMap的取数据的源代码。一看便知:

    private abstract class LinkedHashIterator<T> implements Iterator<T> {
    	Entry<K,V> nextEntry    = header.after;
    	Entry<K,V> lastReturned = null;
    
    	/**
    	 * The modCount value that the iterator believes that the backing
    	 * List should have.  If this expectation is violated, the iterator
    	 * has detected concurrent modification.
    	 */
    	int expectedModCount = modCount;
    
    	public boolean hasNext() {
                return nextEntry != header;
    	}
    
    	public void remove() {
    	    if (lastReturned == null)
    		throw new IllegalStateException();
    	    if (modCount != expectedModCount)
    		throw new ConcurrentModificationException();
    
                LinkedHashMap.this.remove(lastReturned.key);
                lastReturned = null;
                expectedModCount = modCount;
    	}
            //注意点就在这里e.after
    	Entry<K,V> nextEntry() {
    	    if (modCount != expectedModCount)
    		throw new ConcurrentModificationException();
                if (nextEntry == header)
                    throw new NoSuchElementException();
    
                Entry<K,V> e = lastReturned = nextEntry;
                nextEntry = e.after;
                return e;
    	}
        }
    

    HashMap:

    private abstract class HashIterator<E> implements Iterator<E> {
            Entry<K,V> next;	// next entry to return
            int expectedModCount;	// For fast-fail
            int index;		// current slot
            Entry<K,V> current;	// current entry
    
            HashIterator() {
                expectedModCount = modCount;
                if (size > 0) { // advance to first entry
                    Entry[] t = table;
                    while (index < t.length && (next = t[index++]) == null)
                        ;
                }
            }
    
            public final boolean hasNext() {
                return next != null;
            }
            //能够看到,HashMap的取值是从hash表中通过表索引取的,而这个hash表的数据顺序已经在put的时候存储好了
            final Entry<K,V> nextEntry() {
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                Entry<K,V> e = next;
                if (e == null)
                    throw new NoSuchElementException();
    
                if ((next = e.next) == null) {
                    Entry[] t = table;
                    while (index < t.length && (next = t[index++]) == null)
                        ;
                }
    	    current = e;
                return e;
            }
            
            public void remove() {
                if (current == null)
                    throw new IllegalStateException();
                if (modCount != expectedModCount)
                    throw new ConcurrentModificationException();
                Object k = current.key;
                current = null;
                HashMap.this.removeEntryForKey(k);
                expectedModCount = modCount;
            }
    
        }
    

  • 相关阅读:
    【go语言学习】标准库之time
    【go语言学习】文件操作file
    【go语言学习】反射reflect
    【go语言学习】通道channel
    soap添加
    ubuntu apache 启用gzip
    git 版本回退
    ubuntu打开crontab日志及不执行常见原因
    Ionic3 怎么打开第三方 app,最简单粗暴的方法
    Windows安装使用Openssl创建pks p12证书
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10711325.html
Copyright © 2011-2022 走看看