日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

java集合框架类源代码阅读体会

發布時間:2025/6/15 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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集合框架类源代码阅读体会的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。