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

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

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

    posts - 70,comments - 408,trackbacks - 0

    線性表,鏈表,哈希表是常用的數(shù)據(jù)結(jié)構(gòu),在進(jìn)行Java開(kāi)發(fā)時(shí),JDK已經(jīng)為我們提供了一系列相應(yīng)的類來(lái)實(shí)現(xiàn)基本的數(shù)據(jù)結(jié)構(gòu)。這些類均在java.util包中。本文試圖通過(guò)簡(jiǎn)單的描述,向讀者闡述各個(gè)類的作用以及如何正確使用這些類。

     

    Collection

    List

    │├LinkedList

    │├ArrayList

    │└Vector

    │ └Stack

    Set

    Map

    Hashtable

    HashMap

    WeakHashMap

     

    Collection接口

      Collection是最基本的集合接口,一個(gè)Collection代表一組Object,即Collection的元素(Elements)。一些Collection允許相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接繼承自Collection的類,Java SDK提供的類都是繼承自Collection的“子接口”如ListSet

      所有實(shí)現(xiàn)Collection接口的類都必須提供兩個(gè)標(biāo)準(zhǔn)的構(gòu)造函數(shù):無(wú)參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)空的Collection,有一個(gè)Collection參數(shù)的構(gòu)造函數(shù)用于創(chuàng)建一個(gè)新的Collection,這個(gè)新的Collection與傳入的Collection有相同的元素。后一個(gè)構(gòu)造函數(shù)允許用戶復(fù)制一個(gè)Collection

      如何遍歷Collection中的每一個(gè)元素?不論Collection的實(shí)際類型如何,它都支持一個(gè)iterator()的方法,該方法返回一個(gè)迭代子,使用該迭代子即可逐一訪問(wèn)Collection中每一個(gè)元素。典型的用法如下:

        Iterator it = collection.iterator(); // 獲得一個(gè)迭代子

        while(it.hasNext()) {

          Object obj = it.next(); // 得到下一個(gè)元素

        }

      由Collection接口派生的兩個(gè)接口是ListSet

    主要方法:

    boolean add(Object o)添加對(duì)象到集合

    boolean remove(Object o)刪除指定的對(duì)象

    int size()返回當(dāng)前集合中元素的數(shù)量

    boolean contains(Object o)查找集合中是否有指定的對(duì)象

    boolean isEmpty()判斷集合是否為空

    Iterator iterator()返回一個(gè)迭代器

    boolean containsAll(Collection c)查找集合中是否有集合c中的元素

    boolean addAll(Collection c)將集合c中所有的元素添加給該集合

    void clear()刪除集合中所有元素

    void removeAll(Collection c)從集合中刪除c集合中也有的元素

    void retainAll(Collection c)從集合中刪除集合c中不包含的元素

     

    List接口

      List是有序的Collection,使用此接口能夠精確的控制每個(gè)元素插入的位置。用戶能夠使用索引(元素在List中的位置,類似于數(shù)組下標(biāo))來(lái)訪問(wèn)List中的元素,這類似于Java的數(shù)組。

    和下面要提到的Set不同,List允許有相同的元素。

      除了具有Collection接口必備的iterator()方法外,List還提供一個(gè)listIterator()方法,返回一個(gè)ListIterator接口,和標(biāo)準(zhǔn)的Iterator接口相比,ListIterator多了一些add()之類的方法,允許添加,刪除,設(shè)定元素,還能向前或向后遍歷。

      實(shí)現(xiàn)List接口的常用類有LinkedListArrayListVectorStack

    主要方法:

    void add(int index,Object element)在指定位置上添加一個(gè)對(duì)象

    boolean addAll(int index,Collection c)將集合c的元素添加到指定的位置

    Object get(int index)返回List中指定位置的元素

    int indexOf(Object o)返回第一個(gè)出現(xiàn)元素o的位置.

    Object removeint(int index)刪除指定位置的元素

    Object set(int index,Object element)用元素element取代位置index上的元素,返回被取代的元素

     

    LinkedList

      LinkedList實(shí)現(xiàn)了List接口,允許null元素。此外LinkedList提供額外的getremoveinsert方法在LinkedList的首部或尾部。這些操作使LinkedList可被用作堆棧(stack),隊(duì)列(queue)或雙向隊(duì)列(deque)。

      注意LinkedList沒(méi)有同步方法。如果多個(gè)線程同時(shí)訪問(wèn)一個(gè)List,則必須自己實(shí)現(xiàn)訪問(wèn)同步。一種解決方法是在創(chuàng)建List時(shí)構(gòu)造一個(gè)同步的List

        List list = Collections.synchronizedList(new LinkedList(...));

     

    ArrayList

      ArrayList實(shí)現(xiàn)了可變大小的數(shù)組。它允許所有元素,包括nullArrayList沒(méi)有同步。

    sizeisEmptygetset方法運(yùn)行時(shí)間為常數(shù)。但是add方法開(kāi)銷為分?jǐn)偟某?shù),添加n個(gè)元素需要O(n)的時(shí)間。其他的方法運(yùn)行時(shí)間為線性。

      每個(gè)ArrayList實(shí)例都有一個(gè)容量(Capacity),即用于存儲(chǔ)元素的數(shù)組的大小。這個(gè)容量可隨著不斷添加新元素而自動(dòng)增加,但是增長(zhǎng)算法并沒(méi)有定義。當(dāng)需要插入大量元素時(shí),在插入前可以調(diào)用ensureCapacity方法來(lái)增加ArrayList的容量以提高插入效率。

      和LinkedList一樣,ArrayList也是非同步的(unsynchronized)。

    主要方法:

    Boolean add(Object o)將指定元素添加到列表的末尾

    Boolean add(int index,Object element)在列表中指定位置加入指定元素

    Boolean addAll(Collection c)將指定集合添加到列表末尾

    Boolean addAll(int index,Collection c)在列表中指定位置加入指定集合

    Boolean clear()刪除列表中所有元素

    Boolean clone()返回該列表實(shí)例的一個(gè)拷貝

    Boolean contains(Object o)判斷列表中是否包含元素

    Boolean ensureCapacity(int m)增加列表的容量,如果必須,該列表能夠容納m個(gè)元素

    Object get(int index)返回列表中指定位置的元素

    Int indexOf(Object elem)在列表中查找指定元素的下標(biāo)

    Int size()返回當(dāng)前列表的元素個(gè)數(shù)

     

    Vector

      Vector非常類似ArrayList,但是Vector是同步的。由Vector創(chuàng)建的Iterator,雖然和ArrayList創(chuàng)建的Iterator是同一接口,但是,因?yàn)?/SPAN>Vector是同步的,當(dāng)一個(gè)Iterator被創(chuàng)建而且正在被使用,另一個(gè)線程改變了Vector的狀態(tài)(例如,添加或刪除了一些元素),這時(shí)調(diào)用Iterator的方法時(shí)將拋出ConcurrentModificationException,因此必須捕獲該異常。

     

    Stack

      Stack繼承自Vector,實(shí)現(xiàn)一個(gè)后進(jìn)先出的堆棧。Stack提供5個(gè)額外的方法使得Vector得以被當(dāng)作堆棧使用。基本的pushpop方法,還有peek方法得到棧頂?shù)脑兀?/SPAN>empty方法測(cè)試堆棧是否為空,search方法檢測(cè)一個(gè)元素在堆棧中的位置。Stack剛創(chuàng)建后是空棧。

     

    Set接口

      Set是一種不包含重復(fù)的元素的Collection,即任意的兩個(gè)元素e1e2都有e1.equals(e2)=falseSet最多有一個(gè)null元素。

      很明顯,Set的構(gòu)造函數(shù)有一個(gè)約束條件,傳入的Collection參數(shù)不能包含重復(fù)的元素。

      請(qǐng)注意:必須小心操作可變對(duì)象(Mutable Object)。如果一個(gè)Set中的可變?cè)馗淖兞俗陨頎顟B(tài)導(dǎo)致Object.equals(Object)=true將導(dǎo)致一些問(wèn)題。

     

    Map接口

      請(qǐng)注意,Map沒(méi)有繼承Collection接口,Map提供keyvalue的映射。一個(gè)Map中不能包含相同的key,每個(gè)key只能映射一個(gè)valueMap接口提供3種集合的視圖,Map內(nèi)容可以被當(dāng)作一組key集合,一組value集合,或者一組key-value映射。

    主要方法:

    boolean equals(Object o)比較對(duì)象

    boolean remove(Object o)刪除一個(gè)對(duì)象

    put(Object key,Object value)添加key和value

    Hashtable

      Hashtable繼承Map接口,實(shí)現(xiàn)一個(gè)key-value映射的哈希表。任何非空(non-null)的對(duì)象都可作為key或者value

      添加數(shù)據(jù)使用put(key, value),取出數(shù)據(jù)使用get(key),這兩個(gè)基本操作的時(shí)間開(kāi)銷為常數(shù)。

    Hashtable通過(guò)initial capacityload factor兩個(gè)參數(shù)調(diào)整性能。通常缺省的load factor 0.75較好地實(shí)現(xiàn)了時(shí)間和空間的均衡。增大load factor可以節(jié)省空間但相應(yīng)的查找時(shí)間將增大,這會(huì)影響像getput這樣的操作。

    使用Hashtable的簡(jiǎn)單示例如下,將123放到Hashtable中,他們的key分別是”one”,”two”,”three”:

        Hashtable numbers = new Hashtable();

        numbers.put(one, new Integer(1));

        numbers.put(two, new Integer(2));

        numbers.put(three, new Integer(3));

      要取出一個(gè)數(shù),比如2,用相應(yīng)的key

        Integer n = (Integer)numbers.get(two);

        System.out.println(two = + n);

      由于作為key的對(duì)象將通過(guò)計(jì)算其散列函數(shù)來(lái)確定與之對(duì)應(yīng)的value的位置,因此任何作為key的對(duì)象都必須實(shí)現(xiàn)hashCodeequals方法。hashCodeequals方法繼承自根類Object,如果你用自定義的類當(dāng)作key的話,要相當(dāng)小心,按照散列函數(shù)的定義,如果兩個(gè)對(duì)象相同,即obj1.equals(obj2)=true,則它們的hashCode必須相同,但如果兩個(gè)對(duì)象不同,則它們的hashCode不一定不同,如果兩個(gè)不同對(duì)象的hashCode相同,這種現(xiàn)象稱為沖突,沖突會(huì)導(dǎo)致操作哈希表的時(shí)間開(kāi)銷增大,所以盡量定義好的hashCode()方法,能加快哈希表的操作。

      如果相同的對(duì)象有不同的hashCode,對(duì)哈希表的操作會(huì)出現(xiàn)意想不到的結(jié)果(期待的get方法返回null),要避免這種問(wèn)題,只需要牢記一條:要同時(shí)復(fù)寫equals方法和hashCode方法,而不要只寫其中一個(gè)。

      Hashtable是同步的。

     

    HashMap

      HashMapHashtable類似,不同之處在于HashMap是非同步的,并且允許null,即null valuenull key。,但是將HashMap視為Collection時(shí)(values()方法可返回Collection),其迭代子操作時(shí)間開(kāi)銷和HashMap的容量成比例。因此,如果迭代操作的性能相當(dāng)重要的話,不要將HashMap的初始化容量設(shè)得過(guò)高,或者load factor過(guò)低。

     

    WeakHashMap

      WeakHashMap是一種改進(jìn)的HashMap,它對(duì)key實(shí)行“弱引用”,如果一個(gè)key不再被外部所引用,那么該key可以被GC回收。

     

    總結(jié)

      如果涉及到堆棧,隊(duì)列等操作,應(yīng)該考慮用List,對(duì)于需要快速插入,刪除元素,應(yīng)該使用LinkedList,如果需要快速隨機(jī)訪問(wèn)元素,應(yīng)該使用ArrayList

      如果程序在單線程環(huán)境中,或者訪問(wèn)僅僅在一個(gè)線程中進(jìn)行,考慮非同步的類,其效率較高,如果多個(gè)線程可能同時(shí)操作一個(gè)類,應(yīng)該使用同步的類。

      要特別注意對(duì)哈希表的操作,作為key的對(duì)象要正確復(fù)寫equalshashCode方法。

      盡量返回接口而非實(shí)際的類型,如返回List而非ArrayList,這樣如果以后需要將ArrayList換成LinkedList時(shí),客戶端代碼不用改變。這就是針對(duì)抽象編程。

    posted on 2005-11-02 18:48 我心依舊 閱讀(29157) 評(píng)論(10)  編輯  收藏

    FeedBack:
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2007-08-05 16:07 | gongle
    這里的東西比較陳舊了吧,在JDK 1.4中,vector和stack是取消了的  回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2007-09-17 15:55 | 同聲傳譯
    您好,我們公司是一家中國(guó)境內(nèi)的專業(yè)翻譯公司,從事各專業(yè)翻譯服務(wù),包括筆譯、口譯、同聲傳譯和同聲傳譯設(shè)備租賃等。我們需要招聘兼職翻譯、同傳譯員和外籍英文校對(duì)人員。
    希望有機(jī)會(huì)合作.
      回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2007-11-21 12:33 | ONIKAGE
    回一樓:
    沒(méi)看見(jiàn)人家id叫我心依舊么.  回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2009-08-10 22:39 | Alex_Su
    @gongle
    JDK1.6現(xiàn)在都有呢 這篇文章寫的非常的好。  回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2010-07-06 17:07 | 13億寶
    看書(shū)不如看博客  回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2010-07-23 12:44 | kun
    整理得不錯(cuò)。  回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2011-05-20 17:14 | 匆匆路過(guò)
    非常好,我一直不明白hashtable和hashmap的區(qū)別,看過(guò)此文終于明了,謝謝。  回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2012-06-26 13:45 | ygsilence
    好文章,恨透?jìng)?cè)~  回復(fù)  更多評(píng)論
      
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)[未登錄](méi)
    2013-04-02 05:36 | cc
    # re: JAVA數(shù)據(jù)結(jié)構(gòu)
    2013-07-20 22:43 | ss
    好。。。我粘走了  回復(fù)  更多評(píng)論
      

    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 亚洲午夜激情视频| 亚洲av无码兔费综合| 亚洲桃色AV无码| 免费v片在线观看无遮挡| 天天摸天天操免费播放小视频| 久久国产色AV免费看| 国产真人无码作爱视频免费| 一级毛片a免费播放王色| 校园亚洲春色另类小说合集| 亚洲av永久无码| 亚洲综合一区二区三区四区五区 | 99久久99这里只有免费的精品| 午夜亚洲WWW湿好爽| 亚洲国产成人在线视频| 久久精品国产亚洲精品2020| 久久久亚洲欧洲日产国码农村| 无码不卡亚洲成?人片| 成人性生交大片免费看无遮挡| 黄色网址免费大全| 毛片无码免费无码播放| 在线观看特色大片免费网站| 成人无码精品1区2区3区免费看 | 四虎影视永久免费观看| 国产乱子伦片免费观看中字| 国产中文字幕免费| 亚洲AV无码不卡在线观看下载 | 毛片在线全部免费观看| 暖暖免费在线中文日本| 无码精品国产一区二区三区免费 | 亚洲国产精品尤物YW在线观看| 亚洲区小说区图片区QVOD| 亚洲视频一区二区在线观看| 亚洲天然素人无码专区| 暖暖免费中文在线日本| 香蕉成人免费看片视频app下载| 成年网站免费视频A在线双飞| 免费观看午夜在线欧差毛片| 久久精品国产亚洲综合色| 精品亚洲国产成人| 亚美影视免费在线观看| 成人免费视频69|