java集合框架类源代码阅读体会
生活随笔
收集整理的這篇文章主要介紹了
java集合框架类源代码阅读体会
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
忘了什么原因突然想看下JCF,于是就有了這個閱讀體會。?
java版本基于sun jdk1.6.0_18?
1 通用接口?
public interface Iterable<T>?
public interface Iterator<E>?
一個典型的iterator模式的應用。?
注意注釋中提到的Iterator和enumerations一個不同點是方法名的提高,命名還是很重要的。?
public interface Collection<E>?
extends Iterable<E>?
比較有意思。?
線程策略由實現類決定。?
注意contains并不是一定要使用equals,而是把自由給了實現類。?
很多可選操作。?
如果要繼承equals方法需要特別小心,默認的約定是List和Set永遠不相等。?
Java代碼?? //?Query?Operations?? int?size();?? boolean?isEmpty();?? boolean?contains(Object?o);?? Iterator<E>?iterator();?? Object[]?toArray();?? <T>?T[]?toArray(T[]?a);?? ?? //?Modification?Operations?? boolean?add(E?e);?? boolean?remove(Object?o);?? ?? //?Bulk?Operations?? boolean?containsAll(Collection<?>?c);?? boolean?addAll(Collection<??extends?E>?c);?? boolean?removeAll(Collection<?>?c);?? boolean?retainAll(Collection<?>?c);?? void?clear();?? ?? //?Comparison?and?hashing?? boolean?equals(Object?o);?? int?hashCode();??
public abstract class AbstractCollection<E>?
implements Collection<E>?
注意對整數加法溢出的處理。?
用簡單的算法實現給出了Collection的基本實現。?
最大限度的簡化了子類的編寫,同時不限制子類效率更高的寫法。?
public interface Queue<E>?
extends Collection<E>?
public interface Deque<E>?
extends Queue<E>?
Comparator?
注意consistent with equals的意義,即?
c.compare(e1, e2)==0 <=> e1.equals(e2)?
這里可以重溫一下equals和hashcode的關系。?
Comparable?
2 Set ?
public interface Set<E>?
extends Collection<E>?
為了方便copy了Collection<E>所有的方法。?
明確了Set作為對數學上Set的建模。?
對方法做了更為詳盡的注釋。如add不能加入重復元素。?
明確了Set的equals和hashCode的契約。?
equals,只有Set和Set才可能相等,size相同,元素相等。?
hashCode,每一個元素hashCode的和,保持了Object的equals和hashCode的慣用法。?
public abstract class AbstractSet<E>?
extends AbstractCollection<E>?
implements Set<E>?
Set的骨架類。?
簡單實現了equals和hashCode。?
removeAll考慮了使用2個Set中較小的一個做迭代,優化了性能。?
Java代碼?? public?boolean?removeAll(Collection<?>?c)?{?? ????boolean?modified?=?false;?? ?? ????if?(size()?>?c.size())?{?? ????????for?(Iterator<?>?i?=?c.iterator();?i.hasNext();?)?? ????????????modified?|=?remove(i.next());?? ????}?else?{?? ????????for?(Iterator<?>?i?=?iterator();?i.hasNext();?)?{?? ????????????if?(c.contains(i.next()))?{?? ????????????????i.remove();?? ????????????????modified?=?true;?? ????????????}?? ????????}?? ????}?? ????return?modified;?? }??
public class HashSet<E>????
extends AbstractSet<E>????
implements Set<E>, Cloneable, java.io.Serializable?
由HashMap作為存儲。用key來存儲元素,用一個啞元作為所有key對應的value。?
iterator是fail fast的,但是這是一個best effect行為,程序的正確性不應該依賴該異常。?
注意IO序列化的一個自定義實現。writeObject和readObject。?
小技巧:?
HashSet(int initialCapacity, float loadFactor, boolean dummy)?
dummy在這里的作用只是為了和其他的構造函數相區別。?
主要是和public HashSet(int initialCapacity, float loadFactor)區別。?
public class LinkedHashSet<E>????
extends HashSet<E>????
implements Set<E>, Cloneable, java.io.Serializable?
使用了LinkedHashMap保持了元素的插入順序。?
public interface SortedSet<E>?
extends Set<E>?
public interface NavigableSet<E>?
extends SortedSet<E>?
public class TreeSet<E>?
extends AbstractSet<E>?
implements NavigableSet<E>, Cloneable, java.io.Serializable?
和HashSet,LinkedHashSet一樣,都是代理到對應的Map來實現。?
3 List ?
?
public interface List<E>?
extends Collection<E>?
為了方便copy了Collection<E>所有的方法。?
List是有序隊列。?
增加了很多List特定的方法。?
Java代碼?? //?Positional?Access?Operations?? E?get(int?index);?? E?set(int?index,?E?element);?? void?add(int?index,?E?element);?? E?remove(int?index);?? ?? //?Search?Operations?? int?indexOf(Object?o);?? int?lastIndexOf(Object?o);?? ?? //?List?Iterators?? ListIterator<E>?listIterator();?? ListIterator<E>?listIterator(int?index);?? ?? //?View?? List<E>?subList(int?fromIndex,?int?toIndex);??
public interface ListIterator<E>?
extends Iterator<E>?
基于游標的一個列表的Iterator。?
可以前后移動,可以增加,刪除,設置元素。?
public abstract class AbstractList<E>?
extends AbstractCollection<E>?
implements List<E>?
隨機訪問List的骨架類。?
modCount這個字段標識了List結構性被改動的次數,而且子類繼承的時候,該字段是一個可選的字段。?
該類中的Itr,ListItr內部類的實現還是很值得一看一學的。?
同樣,SubList的實現也是比較簡潔的。?
RandomAccessSubList。?
public interface RandomAccess?
這個是一個list的marker interface。?
列表相關的算法由于列表的實現不同性能差異太大。?
public abstract class AbstractSequentialList<E>?
extends AbstractList<E>?
鏈表型列表的骨架類。?
public class ArrayList<E>?
extends AbstractList<E>?
implements List<E>, RandomAccess, Cloneable, java.io.Serializable?
對System.arraycopy方法的大量使用。?
為了少做一點檢查,提高性能,使用fastRemove。?
一般我們都是使用List接口來使用List,直接使用ArrayList可以更好的控制List。當然,沒有特殊需求還是使用List比較方便。?
ArrayList中提供了trimToSize,ensureCapacity來對其內部數據結構做一些控制。?
public class LinkedList<E>?
extends AbstractSequentialList<E>?
implements List<E>, Deque<E>, Cloneable, java.io.Serializable?
使用了啞元的雙向鏈表。?
Clear時,刪除原有所有元素的引用。?
private Entry<E> entry(int index)時不是單向遍歷,而是判斷正向和逆向哪個方向路徑更短,然后決定使用哪個方向查找。?
ListItr.remove() 注意List的ListIterator是雙向的,刪除的時候要判斷前一個動作是什么。?
4 Map ?
public interface Map<K,V>?
interface Entry<K,V>?
public abstract class AbstractMap<K,V>?
implements Map<K,V>?
map的骨架類。?
大量實現是基于entrySet。?
JCF中充滿了類似于?
Java代碼?? ???public?V?get(Object?key)?{?? Iterator<Entry<K,V>>?i?=?entrySet().iterator();?? if?(key==null)?{?? ????while?(i.hasNext())?{?? ????Entry<K,V>?e?=?i.next();?? ????if?(e.getKey()==null)?? ????????return?e.getValue();?? ????}?? }?else?{?? ????while?(i.hasNext())?{?? ????Entry<K,V>?e?=?i.next();?? ????if?(key.equals(e.getKey()))?? ????????return?e.getValue();?? ????}?? }?? return?null;?? ???}??
的代碼,提高性能,避免在每個循環體中比較。?
public static class SimpleEntry<K,V>?
implements Entry<K,V>, java.io.Serializable?
public static class SimpleImmutableEntry<K,V>?
implements Entry<K,V>, java.io.Serializable?
public class HashMap<K,V>?
??? extends AbstractMap<K,V>?
??? implements Map<K,V>, Cloneable, Serializable?
關于capacity, load factor, rehash之間的關系。?
HashMap不是線程安全的。大部分JCF的類都不是線程安全的。?
Capacity必須是2的冪。默認16。Loadfactor默認0.75。?
Map初始化的一個鉤子函數,方便子類實現。?
對于null的特殊處理,所有key為null的都放在index為0的位置。?
內部類,wrapper用的出神入化。?
用鏈表法解決hash沖突。?
public class LinkedHashMap<K,V>?
??? extends HashMap<K,V>?
implements Map<K,V>?
可以是插入順序,也可以是access order。?
使用雙鏈表保持順序。?
public interface SortedMap<K,V>?
extends Map<K,V>?
public interface NavigableMap<K,V>?
extends SortedMap<K,V>?
?
public class TreeMap<K,V>?
extends AbstractMap<K,V>?
implements NavigableMap<K,V>, Cloneable, java.io.Serializable?
底層使用紅黑樹。?
為了性能,在get時對自然序和comparator的分開處理。?
Java代碼?? ???final?Entry<K,V>?getEntry(Object?key)?{?? ???????//?Offload?comparator-based?version?for?sake?of?performance?? ???????if?(comparator?!=?null)?? ???????????return?getEntryUsingComparator(key);?? ???????if?(key?==?null)?? ???????????throw?new?NullPointerException();?? Comparable<??super?K>?k?=?(Comparable<??super?K>)?key;?? ???????Entry<K,V>?p?=?root;?? ???????while?(p?!=?null)?{?? ???????????int?cmp?=?k.compareTo(p.key);?? ???????????if?(cmp?<?0)?? ???????????????p?=?p.left;?? ???????????else?if?(cmp?>?0)?? ???????????????p?=?p.right;?? ???????????else?? ???????????????return?p;?? ???????}?? ???????return?null;?? ???}?? ?? ?? ???final?Entry<K,V>?getEntryUsingComparator(Object?key)?{?? K?k?=?(K)?key;?? ???????Comparator<??super?K>?cpr?=?comparator;?? ???????if?(cpr?!=?null)?{?? ???????????Entry<K,V>?p?=?root;?? ???????????while?(p?!=?null)?{?? ???????????????int?cmp?=?cpr.compare(k,?p.key);?? ???????????????if?(cmp?<?0)?? ???????????????????p?=?p.left;?? ???????????????else?if?(cmp?>?0)?? ???????????????????p?=?p.right;?? ???????????????else?? ???????????????????return?p;?? ???????????}?? ???????}?? ???????return?null;?? ???}??
果然還是TreeMap的代碼最難讀懂。?
Java代碼?? ????final?Entry<K,V>?getCeilingEntry(K?key)?{?? ????????Entry<K,V>?p?=?root;?? ????????while?(p?!=?null)?{?? ????????????int?cmp?=?compare(key,?p.key);?? //進入到左子樹,說明該子樹的root比key大。?? ????????????if?(cmp?<?0)?{?? ????????????????if?(p.left?!=?null)?? ????????????????????p?=?p.left;?? ????????????????else?? ????????????????????return?p;?? ????????????}?else?if?(cmp?>?0)?{?? ????????????????if?(p.right?!=?null)?{?? ????????????????????p?=?p.right;?? ????????????????}?else?{?? //如果是左子樹進來的,查找該左子樹的root。如果不是,結果是null。?? ????????????????????Entry<K,V>?parent?=?p.parent;?? ????????????????????Entry<K,V>?ch?=?p;?? ????????????????????while?(parent?!=?null?&&?ch?==?parent.right)?{?? ????????????????????????ch?=?parent;?? ????????????????????????parent?=?parent.parent;?? ????????????????????}?? ????????????????????return?parent;?? ????????????????}?? ????????????}?else?? ????????????????return?p;?? ????????}?? ????????return?null;?? ????}??
TreeMap可以插入為null的key,但是插入后,該TreeMap基本就不能使用了。?
Java代碼?? @Test(expected?=?NullPointerException.class)?? public?void?testAddNullToTreeMap()?{?? ????TreeMap<String,?String>?tm?=?new?TreeMap<String,?String>();?? ????tm.put(null,?"test");?? ????tm.get("key");?? }??
View返回的都是快照(SimpleImmutableEntry),無法setValue,但是可以使用map的put方法來改變值。?
紅黑樹的插入以前一直沒有看,現在一看果然精彩。?
注意紅黑樹刪除元素時的特殊處理。?
Java代碼?? //?deleted?entries?are?replaced?by?their?successors?? if?(lastReturned.left?!=?null?&&?lastReturned.right?!=?null)?? ????next?=?lastReturned;??
最后的構建紅黑樹也比較有意思,如果一個完全二叉樹,最后一層不滿的話,則全部為RED。?
小結 ?
1 漂亮的注釋:JCF的注釋的確是比較漂亮的,簡單清晰。唯一的不足就是為了保持每個方法注釋的完整性,導致有很多重復的注釋。當然,對于使用方法有需要才去看注釋的程序員來說,這樣更方便一點,但是對于完整閱讀代碼的人來說,貌似有點多余。?
2 勿以善小而不為:當看到Iterator的類說明中有改善命名一條時,真的有點感動。?
3 大師級的設計和代碼復用技術。這個沒有什么好說的,喜愛代碼的人是在看藝術品。?
4 框架代碼對性能的有限度強調:在可以提高性能的地方提高性能,但是并不阻止其他人實現子類時提供性能更好的方法。同時,代碼并沒有因為對一些性能問題的特殊處理而變得丑陋。?
5 關于類線程安全性的注釋:一般代碼哪里看的到這個。?
6 幾個骨架類的設計和實現都很簡潔有力,僅僅使用幾個基本方法,就可以實現接口的所有功能。?
7 modCount思想。fail-fast的實現機制。?
8 平時還是要打好基礎,數據結構和算法中對紅黑數的插入和刪除以前沒有怎么看過,只知道概念和用途,直接導致看到TreeMap的時候比較費力。?
9 一行行讀代碼未必是一個好辦法,對于JCF的接口和類的體系還是比較熟悉的,因此沒有什么問題,但是Map的Iterator和View的繼承體系以前沒有接觸過,看完過自己覺得沒有清晰的把握設計思路,動手畫畫圖,真是有如泰山登頂,一覽天下的感覺,神清氣爽啊。?
10 優秀的源代碼還是應該早讀的,有點后悔為什么拖到現在才開始看JCF,以前干嘛去了。?
11 強烈推薦大家都看看JCF。
java版本基于sun jdk1.6.0_18?
1 通用接口?
public interface Iterable<T>?
public interface Iterator<E>?
一個典型的iterator模式的應用。?
注意注釋中提到的Iterator和enumerations一個不同點是方法名的提高,命名還是很重要的。?
public interface Collection<E>?
extends Iterable<E>?
比較有意思。?
線程策略由實現類決定。?
注意contains并不是一定要使用equals,而是把自由給了實現類。?
很多可選操作。?
如果要繼承equals方法需要特別小心,默認的約定是List和Set永遠不相等。?
Java代碼??
public abstract class AbstractCollection<E>?
implements Collection<E>?
注意對整數加法溢出的處理。?
用簡單的算法實現給出了Collection的基本實現。?
最大限度的簡化了子類的編寫,同時不限制子類效率更高的寫法。?
public interface Queue<E>?
extends Collection<E>?
public interface Deque<E>?
extends Queue<E>?
Comparator?
注意consistent with equals的意義,即?
c.compare(e1, e2)==0 <=> e1.equals(e2)?
這里可以重溫一下equals和hashcode的關系。?
Comparable?
2 Set ?
public interface Set<E>?
extends Collection<E>?
為了方便copy了Collection<E>所有的方法。?
明確了Set作為對數學上Set的建模。?
對方法做了更為詳盡的注釋。如add不能加入重復元素。?
明確了Set的equals和hashCode的契約。?
equals,只有Set和Set才可能相等,size相同,元素相等。?
hashCode,每一個元素hashCode的和,保持了Object的equals和hashCode的慣用法。?
public abstract class AbstractSet<E>?
extends AbstractCollection<E>?
implements Set<E>?
Set的骨架類。?
簡單實現了equals和hashCode。?
removeAll考慮了使用2個Set中較小的一個做迭代,優化了性能。?
Java代碼??
public class HashSet<E>????
extends AbstractSet<E>????
implements Set<E>, Cloneable, java.io.Serializable?
由HashMap作為存儲。用key來存儲元素,用一個啞元作為所有key對應的value。?
iterator是fail fast的,但是這是一個best effect行為,程序的正確性不應該依賴該異常。?
注意IO序列化的一個自定義實現。writeObject和readObject。?
小技巧:?
HashSet(int initialCapacity, float loadFactor, boolean dummy)?
dummy在這里的作用只是為了和其他的構造函數相區別。?
主要是和public HashSet(int initialCapacity, float loadFactor)區別。?
public class LinkedHashSet<E>????
extends HashSet<E>????
implements Set<E>, Cloneable, java.io.Serializable?
使用了LinkedHashMap保持了元素的插入順序。?
public interface SortedSet<E>?
extends Set<E>?
public interface NavigableSet<E>?
extends SortedSet<E>?
public class TreeSet<E>?
extends AbstractSet<E>?
implements NavigableSet<E>, Cloneable, java.io.Serializable?
和HashSet,LinkedHashSet一樣,都是代理到對應的Map來實現。?
3 List ?
?
public interface List<E>?
extends Collection<E>?
為了方便copy了Collection<E>所有的方法。?
List是有序隊列。?
增加了很多List特定的方法。?
Java代碼??
public interface ListIterator<E>?
extends Iterator<E>?
基于游標的一個列表的Iterator。?
可以前后移動,可以增加,刪除,設置元素。?
public abstract class AbstractList<E>?
extends AbstractCollection<E>?
implements List<E>?
隨機訪問List的骨架類。?
modCount這個字段標識了List結構性被改動的次數,而且子類繼承的時候,該字段是一個可選的字段。?
該類中的Itr,ListItr內部類的實現還是很值得一看一學的。?
同樣,SubList的實現也是比較簡潔的。?
RandomAccessSubList。?
public interface RandomAccess?
這個是一個list的marker interface。?
列表相關的算法由于列表的實現不同性能差異太大。?
public abstract class AbstractSequentialList<E>?
extends AbstractList<E>?
鏈表型列表的骨架類。?
public class ArrayList<E>?
extends AbstractList<E>?
implements List<E>, RandomAccess, Cloneable, java.io.Serializable?
對System.arraycopy方法的大量使用。?
為了少做一點檢查,提高性能,使用fastRemove。?
一般我們都是使用List接口來使用List,直接使用ArrayList可以更好的控制List。當然,沒有特殊需求還是使用List比較方便。?
ArrayList中提供了trimToSize,ensureCapacity來對其內部數據結構做一些控制。?
public class LinkedList<E>?
extends AbstractSequentialList<E>?
implements List<E>, Deque<E>, Cloneable, java.io.Serializable?
使用了啞元的雙向鏈表。?
Clear時,刪除原有所有元素的引用。?
private Entry<E> entry(int index)時不是單向遍歷,而是判斷正向和逆向哪個方向路徑更短,然后決定使用哪個方向查找。?
ListItr.remove() 注意List的ListIterator是雙向的,刪除的時候要判斷前一個動作是什么。?
4 Map ?
public interface Map<K,V>?
interface Entry<K,V>?
public abstract class AbstractMap<K,V>?
implements Map<K,V>?
map的骨架類。?
大量實現是基于entrySet。?
JCF中充滿了類似于?
Java代碼??
的代碼,提高性能,避免在每個循環體中比較。?
public static class SimpleEntry<K,V>?
implements Entry<K,V>, java.io.Serializable?
public static class SimpleImmutableEntry<K,V>?
implements Entry<K,V>, java.io.Serializable?
public class HashMap<K,V>?
??? extends AbstractMap<K,V>?
??? implements Map<K,V>, Cloneable, Serializable?
關于capacity, load factor, rehash之間的關系。?
HashMap不是線程安全的。大部分JCF的類都不是線程安全的。?
Capacity必須是2的冪。默認16。Loadfactor默認0.75。?
Map初始化的一個鉤子函數,方便子類實現。?
對于null的特殊處理,所有key為null的都放在index為0的位置。?
內部類,wrapper用的出神入化。?
用鏈表法解決hash沖突。?
public class LinkedHashMap<K,V>?
??? extends HashMap<K,V>?
implements Map<K,V>?
可以是插入順序,也可以是access order。?
使用雙鏈表保持順序。?
public interface SortedMap<K,V>?
extends Map<K,V>?
public interface NavigableMap<K,V>?
extends SortedMap<K,V>?
?
public class TreeMap<K,V>?
extends AbstractMap<K,V>?
implements NavigableMap<K,V>, Cloneable, java.io.Serializable?
底層使用紅黑樹。?
為了性能,在get時對自然序和comparator的分開處理。?
Java代碼??
果然還是TreeMap的代碼最難讀懂。?
Java代碼??
TreeMap可以插入為null的key,但是插入后,該TreeMap基本就不能使用了。?
Java代碼??
View返回的都是快照(SimpleImmutableEntry),無法setValue,但是可以使用map的put方法來改變值。?
紅黑樹的插入以前一直沒有看,現在一看果然精彩。?
注意紅黑樹刪除元素時的特殊處理。?
Java代碼??
最后的構建紅黑樹也比較有意思,如果一個完全二叉樹,最后一層不滿的話,則全部為RED。?
小結 ?
1 漂亮的注釋:JCF的注釋的確是比較漂亮的,簡單清晰。唯一的不足就是為了保持每個方法注釋的完整性,導致有很多重復的注釋。當然,對于使用方法有需要才去看注釋的程序員來說,這樣更方便一點,但是對于完整閱讀代碼的人來說,貌似有點多余。?
2 勿以善小而不為:當看到Iterator的類說明中有改善命名一條時,真的有點感動。?
3 大師級的設計和代碼復用技術。這個沒有什么好說的,喜愛代碼的人是在看藝術品。?
4 框架代碼對性能的有限度強調:在可以提高性能的地方提高性能,但是并不阻止其他人實現子類時提供性能更好的方法。同時,代碼并沒有因為對一些性能問題的特殊處理而變得丑陋。?
5 關于類線程安全性的注釋:一般代碼哪里看的到這個。?
6 幾個骨架類的設計和實現都很簡潔有力,僅僅使用幾個基本方法,就可以實現接口的所有功能。?
7 modCount思想。fail-fast的實現機制。?
8 平時還是要打好基礎,數據結構和算法中對紅黑數的插入和刪除以前沒有怎么看過,只知道概念和用途,直接導致看到TreeMap的時候比較費力。?
9 一行行讀代碼未必是一個好辦法,對于JCF的接口和類的體系還是比較熟悉的,因此沒有什么問題,但是Map的Iterator和View的繼承體系以前沒有接觸過,看完過自己覺得沒有清晰的把握設計思路,動手畫畫圖,真是有如泰山登頂,一覽天下的感覺,神清氣爽啊。?
10 優秀的源代碼還是應該早讀的,有點后悔為什么拖到現在才開始看JCF,以前干嘛去了。?
11 強烈推薦大家都看看JCF。
總結
以上是生活随笔為你收集整理的java集合框架类源代码阅读体会的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JAVA线程池(ThreadPoolEx
- 下一篇: WinCE驱动开发