<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    javaGrowing

      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
      92 隨筆 :: 33 文章 :: 49 評論 :: 0 Trackbacks

    數組與其它容器的區別體現在三個方面:效率,類型識別以及可以持有primitives.

    數組是java提供的,是能隨機存儲和訪問reference序列的諸多方法中,最高效的一種。數組是線形序列,所以它可以快速訪問其中的元素,但速度是有代價的,當你創建了一個數組之后它的容量就固定了,而且在其生命周期里不能改變。也許你會提議先創建一個數組,等到快不夠用的時候,再創建一個新的,然后將舊數組里的reference 全部導到新的里面。其實ArrayList 就是這么做的。但是這種靈活性所帶來的開銷,使得ArrayList 的效率比       起數組有了明顯下降。      

    在我們寫程序的時候往往不知道要用多少對象,或者要用一種更復雜方式來存儲對象情況。為此,Java 提供了“容器類(container class)”。其基本類型有List, Set Map。有了這些工具,你就能解決很多問題了。它們還有一些別的特性。比方說Set 所持有的對象,個個都不同,Map則是一個“關聯性數組(associative array)”,它能在兩個對象之間建立聯系。此外,與數組不同,它們還能自動調整大小,所以你可以往里面放任意數量的對象。這樣寫程序的時候,就不用操心要開多大的空間了。

     

    Java2 的容器類要解決“怎樣持有對象”,而它把這個問題分成兩類:

    1. Collection: 通常是一組有一定規律的獨立元素。List 必須按照特定的順序持有這些元素,而Set 則不能保存重復的元素。(bag沒有這個限制,但是Java的容器類庫沒有實現它,因為List 已經提供這種功能了。)

    2. Map: 一組以“鍵——值”(key-value)形式出現的pair。初看上去,它應該是一個pairCollection,但是真這么去做的話,它就會變得很滑稽,所以還是把這個概念獨立列出來為好。退一步說,真的要用到Map 的某個子集的時候,創建一個Collection 也是很方便的。Map可以返回“鍵(key)的”Set,值的Collection,或者pairSet。和數組一樣,Map 不需要什么修改,就能很容易地擴展成多維。你只要直接把Map 的值設成Map 就可以了(然后它的值再是Map,以此類推)。我們先來看看容器的一般特性,然后深入細節,最后再看什么會有這么多版本,以及如何進行選擇。

     

    List 會老老實實地持有你所輸入的所有對象,既不做排序也不做編輯。Set 則每個對象只接受一次,而且還要用它自己的規則對元素進行重新排序(一般情況下,你關心的只是Set 包沒包括某個對象,而不是它到底排在哪里——如果是那樣,你最好還是用List)。而Map 也不接收重復的pair,至于是不是重復,要由key來決定。此外,它也有它自己的內部排序規則,不會受輸入順序影響。如果插入順序是很重要的,那你就只能使用LinkedHashSet LinkedHashMap 了。

    test.bmp

    第一眼看到這張圖的時候,你會覺得很震撼。不過你馬上就會知道,實際上只有三種容器組件——Map,List 和Set,而每種又有兩到三個實現。最常用的幾個容器已經用粗黑線框了起來。看到這里,這張圖就不再那么令人望而生畏了。
    用點號框起來的是interface,用虛線框起來的是abstract 類,實線
    則表示普通的(“實體concrete”)類。點線的箭頭表示類實現了這個interface(或者,abstract 類表示部分實現了這個interface)。實線
    箭頭表示這個類可以制造箭頭所指的那個類的對象。比如,Collection
    能制造Iterator,而List 還能制造ListIterator(也能制造Iterator,因為List 是繼承自Collection 的)。
    與存放對象有關的接口包括Collection,List,Set 和Map。在理想情況下,絕大多數代碼應該只同這些接口打交道,只是在創建容器的時候才要精確地指明它的確切類型。所以你可以這樣創建一個List。
    List x = new LinkedList( );

    當然,你也可以選擇讓x 成為LinkedList(而不是泛型的List),這樣x 就帶上了準確的類型信息interface 的優雅 (同時也是它的本意)就在于,你想修改具體的實現的時候,只要改一下創建的聲明就可以了,就
    像這樣:
    List x = new ArrayList( );
    無需驚動其它代碼(用迭代器也能獲得一些這種泛型性)。這個類系里面有很多以“Abstract”開頭的類,初看起來這可能會讓人有點不明白。實際上它們只是一些部分實現某個接口的辦成品。假如你要編一個你自己的Set,不要從Set 接口開始挨個實現它的方法;相反你最好繼承AbstractSet,這樣就能把編程的工作量壓縮到最低了。但是,實際上容器類庫的功能已經夠強的了,我們要求的事情它幾乎都能做
    到。所以對我們來說,你完全可以忽略以“Abstract”開頭的類。

    List 的功能
    正如你從ArrayList 那里所看到的,List 的基本用法是相當簡單的。雖然絕大多數時候,你只是用add( )加對象,用get( )取對象,用iterator( )獲取這個序列的Iterator,但List 還有一些別的很有用的
    方法。
    實際上有兩種List:擅長對元素進行隨機訪問的,較常用的ArrayList,和更強大的LinkedList。LinkedList 不是為快速的隨機訪問而設計的,但是它卻有一組更加通用的方法。

    List (接口) List 的最重要的特征就是有序;它會確保以一定的順序保存元素。List 在Collection 的基礎上添加了大量方法,使之能在序列中間插入和刪除元素。(只對LinkedList 推薦使用。)List 可以制造ListIterator 對象,你除了能用它在List 的中間插入和刪除元素之外,還能用它沿兩個方向遍歷List。
    ArrayList*一個用數組實現的List。能進行快速的隨機訪問, 但是往列表中間插入和刪除元素的時候比較慢。ListIterator 只能用在反向遍歷ArrayList 的場 合,不要用它來插入和刪除元素,因為相比LinkedList,在ArrayList 里面用ListIterator 的系統開銷比較高。
    LinkedList對順序訪問進行了優化。在List 中間插入和刪除元 素的代價也不高。隨機訪問的速度相對較慢。(用ArrayList 吧。)此外它還有addFirst( ), addLast( ),getFirst( ),getLast( ), removeFirst( )和removeLast( )等方法(這些 方法,接口和基類均未定義),你能把它當成棧(stack),隊列(queue)或雙向隊列(deque)來用。 下面這段程序把各種操作都集中到方法里面:List 都能作的事(basicTest( )),用Iterator 在列表中移動(iterMotion( )),修改 列表的元素(iterManipulation( )),查看List 的操作結果(testVisual( )),以及LinkedList 所獨有的方法。
    Set 的功能
    Set 的接口就是Collection 的,所以不像那兩個List,它沒有額外的
    功能。實際上Set 確確實實就是一個Collection——只不過行為方式不
    同罷了。(這是繼承和多態性的完美運用:表達不同地行為。)Set 會拒絕
    持有多個具有相同值的對象的實例(對象的“值”又是由什么決定的呢?
    這個問題比較復雜,我們以后會講的)。
    Set (接口)加入Set 的每個元素必須是唯一的;否則, Set 是不會把它加進去的。要想加進Set, Object 必須定義equals( ),這樣才能標明對象的唯一性。Set 的接口和Collection 的
    一模一樣。Set 的接口不保證它會用哪種順序來存儲元素。
    HashSet* 為優化查詢速度而設計的Set。要放進HashSet 里面的Object 還得定義hashCode( )。
    TreeSet 是一個有序的Set,其底層是一棵樹。這樣你 就能從Set 里面提取一個有序序列了。
    LinkedHashSet(JDK 1.4) 一個在內部使用鏈表的Set,既有HashSet 的查詢速度,又能保存元素被加進去的順序(插入順序)。用Iterator 遍歷Set 的時候, 它是按插入順序進行訪問的。
    Map 的功能
    ArrayList 能讓你用數字在一個對象序列里面進行選擇,所以從某種意義上講,它是將數字和對象關聯起來。但是,如果你想根據其他條件在一個對象序列里面進行選擇的話,那又該怎么做呢?從概念上講,它看上去像是一個ArrayList,但它不用數字,而是用另一個對象來查找對象!這是一種至關重要的編程技巧。這一概念在Java 中表現為Map。put(Object key, Object value)方法會往Map 里面加一個值,并且把這個值同鍵(你查找時所用的對象)聯系起來。給出鍵之后,get(Object key)就會返回與之相關聯的值。
    你也可以用containsKey( ) 和 containsValue( )測試Map 是否包含有某個鍵或值。
    Java 標準類庫里有好幾種Map:HashMap,TreeMap, LinkedHashMap,WeakHashMap,IdentityHashMap。
    它們都實現了Map 的基本接口,但是在行為方式方面有著明顯的差異。這些差異體現在,效率,持有和表示對象pair 的順序,持有對象的時間長短,以及如何決定鍵的相等性。性能是Map 所要面對的一個大問題。如果你知道get( )是怎么工作的,你就會發覺(比方說)在ArrayList 里面找對象會是相當慢的。而這
    正是HashMap 的強項。它不是慢慢地一個個地找這個鍵,而是用了一種被稱為hash code的特殊值來進行查找的。散列(hash)是一種算法,它會從目標對象當中提取一些信息,然后生成一個表示這個對象的“相對
    獨特”的int。hashCode( )是Object 根類的方法,因此所有Java對象都能生成hash code。HashMap 則利用對象的hashCode( )來進行快速的查找。這樣性能就有了急劇的提高。

    Map (接口)維持鍵-值的關聯(即pairs),這樣就能用鍵來找值了。
    HashMap* 基于hash表的實現。(用它來代替Hashtable。)提供時間恒定的插入與查詢。在構造函數中可以設置 hash表的capacity 和load factor。可以通過構造 函數來調節其性能。
    LinkedHashMap(JDK 1.4) 很像HashMap,但是用Iterator 進行 遍歷的時候,它會按插入順序或最先使用 的順序(least-recently-used (LRU) order)進行訪問。除了用Iterator 外, 其他情況下,只是比HashMap 稍慢一 點。用Iterator 的情況下,由于是使用 鏈表來保存內部順序,因此速度會更快。
    TreeMap 基于紅黑樹數據結構的實現。當你查看鍵 或pair 時,會發現它們是按順序 (根據Comparable 或Comparator,我們過 一會講)排列的。TreeMap 的特點是,你 所得到的是一個有序的Map。TreeMap 是Map 中唯一有subMap( )方法的實 現。這個方法能讓你獲取這個樹中的一部 分。
    WeakHashMap 一個weak key的Map,是為某些特殊問 題而設計的。它能讓Map 釋放其所持有的 對象。如果某個對象除了在Map 當中充當 鍵之外,在其它地方都沒有其reference 的話,那它將被當作垃圾回收。
    IdentityHashMap(JDK 1.4) 一個用==,而不是equals( )來比較鍵 的hash map。不是為我們平常使用而設 計的,是用來解決特殊問題的。 散列是往Map 里存數據的常用算法。有時你會需要知道散列算法的工作 細節,所以我們會稍后再講。
    posted on 2005-12-09 11:09 javaGrowing 閱讀(2729) 評論(1)  編輯  收藏 所屬分類: java 學習

    評論

    # re: java對象容器 2005-12-09 11:29 黃海軍
    確實是跟.net幾乎一樣的了  回復  更多評論
      

    主站蜘蛛池模板: 午夜在线免费视频 | 日产亚洲一区二区三区| 免费看一级一级人妻片 | 亚洲AV无码专区国产乱码不卡| 国产人成免费视频网站| 亚洲电影在线播放| 成人免费大片免费观看网站| 亚洲国产理论片在线播放| 一二三四影视在线看片免费| 亚洲一区二区三区91| 成年女人喷潮毛片免费播放| 亚洲AV无码AV男人的天堂不卡| 啊灬啊灬别停啊灬用力啊免费看| 美女黄色毛片免费看| 国产成人综合亚洲AV第一页| 免费在线看黄网站| 亚洲性无码av在线| 在线精品免费视频无码的| 免费看一级高潮毛片| 亚洲成在人天堂一区二区| 最近免费中文字幕mv在线电影| 亚洲一区二区三区在线网站| 国产成人无码区免费A∨视频网站| 无人视频免费观看免费视频| 日本亚洲欧洲免费天堂午夜看片女人员| 你是我的城池营垒免费观看完整版| 久久久久久a亚洲欧洲AV| 在线观看av永久免费| 青青久久精品国产免费看| 国产亚洲精品va在线| 91在线视频免费看| sss在线观看免费高清| 亚洲电影在线免费观看| 国产免费人人看大香伊| 久久99精品视免费看| 亚洲精品色播一区二区| 亚洲国产精品一区二区第一页| 韩国免费一级成人毛片| 色老头综合免费视频| 亚洲一区二区三区久久| 亚洲无码在线播放|