集合框架map学习笔记一LinkedHashMap
2013-03-26 22:34
92 查看
Map:
1、HashMap
2、LinkedHashMap
3、IdentityHashMap
4、WeakHashMap
5、TreeMap
6、EnumMap
7、ConcurrentHashMap
8、ConcurrentSkipListMap
今天主要学习的是LinkedHashMap。
1、LinkedHashMap
LinkedHashMap是继承HashMap的一个子类,所有存储的结构也是Entry[],同样是以key的hashCode值来计算key-value所在的Entry[]桶所在的下标。来实现快速的存放和查询。但是LinkedHashMap除了继承父类HashMap的功能以外,解决了HashMap无序的问题。
LinkedHashMap遍历元素的时候,遍历的顺序是以数据的存入的顺序。
2、LinkedHashMap的数据存放
因为LinkedHashMap在HashMap的Entry[]对象中,继承Entry对象扩充了自己的Entry对象能力,增加了before和after属性,使得数据存入以后,成为一个双向链表的形式。因为双向链表的处理,所以LinkedHashMap的数据写入性能没有HashMap高。
LinkedHashMap的数据写入也是调用父类的put方法(已经在HashMap里面介绍了put方法了),而重写了addEntry方法。对于Entry对象的处理,主要在于建立双向链表,使得由header对象开始,与每次加入的对象成为双向链表。
2、LinkedHashMap的数据获取
LinkedHashMap的get方法其实和HashMap的get方法实现是一致的,但是HashMap的get方法,在null值的判断上处理了两次,一次是get方法中,一次在底层调用getEntry方法的时候也判断了一次,而LinkedHashMap对这里进行了优化,只在getEntry中去判断就可以了。
LinkedHashMap中key值为null的情况,仍然和HashMap一样放在Entry[0]中,也就是桶的首位。
特别之处在于accessOrder为true的情况,后面再讲。
3、LinkedHashMap的数据遍历
LinkedHashMap也是一般通过keySet方法进行key值的遍历。而LinkedHashMap的迭代器并不是像HashMap一样先遍历桶(Entry[])的,而是由header元素开始慢慢的next读取after对象。所以读取的顺序和写入的顺序一致。
3、LinkedHashMap的特别属性
LinkedHashMap虽然继承了HashMap的结构存储数据,但是除了HashMap的相关属性以外,还特别添加了:
3.1、Header属性,来存储双向链表的关系。
3.2、accessOrder属性,这个属性主要是控制链表的顺序的,如果accessOrder为false(默认为false),遍历LinkedHashMap的时候,返回的数据顺序为写入的顺序,如果为true,则返回数据的顺序为读取的顺序。
注意:如果accessOrder为true,get方法中也在修改LinkedHashMap,所以不能一边遍历LinkedHashMap,一边从LinkedHashMap中get获取对象,否则会抛出ConcurrentModificationException
下面的例子主要是针对accessOrder为true的证实
结果为:
2
4
3
5
1
1、HashMap
2、LinkedHashMap
3、IdentityHashMap
4、WeakHashMap
5、TreeMap
6、EnumMap
7、ConcurrentHashMap
8、ConcurrentSkipListMap
今天主要学习的是LinkedHashMap。
1、LinkedHashMap
LinkedHashMap是继承HashMap的一个子类,所有存储的结构也是Entry[],同样是以key的hashCode值来计算key-value所在的Entry[]桶所在的下标。来实现快速的存放和查询。但是LinkedHashMap除了继承父类HashMap的功能以外,解决了HashMap无序的问题。
LinkedHashMap遍历元素的时候,遍历的顺序是以数据的存入的顺序。
2、LinkedHashMap的数据存放
因为LinkedHashMap在HashMap的Entry[]对象中,继承Entry对象扩充了自己的Entry对象能力,增加了before和after属性,使得数据存入以后,成为一个双向链表的形式。因为双向链表的处理,所以LinkedHashMap的数据写入性能没有HashMap高。
LinkedHashMap的数据写入也是调用父类的put方法(已经在HashMap里面介绍了put方法了),而重写了addEntry方法。对于Entry对象的处理,主要在于建立双向链表,使得由header对象开始,与每次加入的对象成为双向链表。
/** * This override alters behavior of superclass put method. It causes newly * allocated entry to get inserted at the end of the linked list and * removes the eldest entry if appropriate. */ void addEntry(int hash, K key, V value, int bucketIndex) { createEntry(hash, key, value, bucketIndex); // Remove eldest entry if instructed, else grow capacity if appropriate Entry<K,V> eldest = header.after; if (removeEldestEntry(eldest)) { removeEntryForKey(eldest.key); } else { if (size >= threshold) resize(2 * table.length); } }
void createEntry(int hash, K key, V value, int bucketIndex) { HashMap.Entry<K,V> old = table[bucketIndex]; Entry<K,V> e = new Entry<K,V>(hash, key, value, old); table[bucketIndex] = e; e.addBefore(header); size++; }
/** * Inserts this entry before the specified existing entry in the list. */ private void addBefore(Entry<K,V> existingEntry) { after = existingEntry; before = existingEntry.before; before.after = this; after.before = this; }
2、LinkedHashMap的数据获取
LinkedHashMap的get方法其实和HashMap的get方法实现是一致的,但是HashMap的get方法,在null值的判断上处理了两次,一次是get方法中,一次在底层调用getEntry方法的时候也判断了一次,而LinkedHashMap对这里进行了优化,只在getEntry中去判断就可以了。
LinkedHashMap中key值为null的情况,仍然和HashMap一样放在Entry[0]中,也就是桶的首位。
特别之处在于accessOrder为true的情况,后面再讲。
3、LinkedHashMap的数据遍历
LinkedHashMap也是一般通过keySet方法进行key值的遍历。而LinkedHashMap的迭代器并不是像HashMap一样先遍历桶(Entry[])的,而是由header元素开始慢慢的next读取after对象。所以读取的顺序和写入的顺序一致。
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; } 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; } }
3、LinkedHashMap的特别属性
LinkedHashMap虽然继承了HashMap的结构存储数据,但是除了HashMap的相关属性以外,还特别添加了:
3.1、Header属性,来存储双向链表的关系。
3.2、accessOrder属性,这个属性主要是控制链表的顺序的,如果accessOrder为false(默认为false),遍历LinkedHashMap的时候,返回的数据顺序为写入的顺序,如果为true,则返回数据的顺序为读取的顺序。
注意:如果accessOrder为true,get方法中也在修改LinkedHashMap,所以不能一边遍历LinkedHashMap,一边从LinkedHashMap中get获取对象,否则会抛出ConcurrentModificationException
下面的例子主要是针对accessOrder为true的证实
public class TestLinkedHashMap { /** * @param args */ public static void main(String[] args) { LinkedHashMap<Integer, String> hm1 = new LinkedHashMap<Integer, String>(16, 0.75f,true); hm1.put(1,"1"); hm1.put(2,"2"); hm1.put(3,"3"); hm1.put(4,"4"); hm1.put(5,"5"); hm1.get(2); hm1.get(4); hm1.get(3); hm1.get(5); hm1.get(1); Iterator iter1 = hm1.keySet().iterator(); while(iter1.hasNext()){ System.out.println(iter1.next()); } } }
结果为:
2
4
3
5
1
相关文章推荐
- Java基础学习笔记十七 集合框架(三)之Map
- 集合框架map学习笔记一IdentityHashMap
- (37)Java学习笔记——集合框架 / Map集合
- 集合框架map学习笔记-WeakHashMap
- 黑马程序员_学习笔记:10) 集合框架2:Set(HashSet、TreeSet)、Map(Hashtable、HashMap、TreeMap)、Collections、Arrays
- 集合框架map学习笔记一HashMap
- 黑马程序员----Java集合框架学习笔记2 Map-工具类-泛型
- Java学习笔记---集合框架
- Java基础学习笔记十六 集合框架(二)
- Java基础知识强化之集合框架笔记50:Map集合之Map集合的概述和特点
- Java集合源码学习笔记(一)集合框架概览
- JavaSE中Map框架学习笔记
- Android(java)学习笔记103:Map集合的获取功能
- java学习日记_86:集合框架之Map
- java学习笔记:集合框架之TreeSet
- Java基础知识强化之集合框架笔记55:Map集合之HashMap集合(HashMap<Integer,String>)的案例
- JAVAOOP—第六章(集合框架)学习笔记
- java第十四章学习笔记:集合框架---强大的对象管理器
- 黑马程序员-集合框架的学习笔记-2
- 【Java学习笔记】14.集合框架和泛型