亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

Java集合框架的講解

2019-11-06 06:44:53
字體:
來源:轉載
供稿:網友

學習java的同學注意了?。。?nbsp;學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:523047986  我們一起學Java!

  下面要開始java中相關集合框架的學習啦。

  Are you ready?Let's go~~

  今天要講解的Java中的集合框架。

  1) 首先查看jdk中Collection類的源碼后會發現如下內容:

    

1234567... * @see     AbstractCollection @since 1.2 */ public interface Collection<e> extends Iterable<e> {    // Query Operations</e></e>

  通過查看可以發現Collection是一個接口類,其繼承了java迭代接口Iterable。

 

  眾所周知在我們使用Java中的類的存儲的時候經常會使用一些容器,鏈表的概念,本文將徹底幫您弄清鏈表的各種概念和模型?。。?!

  注意理解哦~~~ 大致框架如下:                                                                            

  Collection接口有兩個主要的子接口List和Set,注意Map不是Collection的子接口哦這個要牢記。

  Collection中可以存儲的元素間無序,可以重復組各 自獨立的元素, 即其內的每個位置僅持有一個元素,同時允許有多個null元素對象。

  Collection接口中的方法如下:

  

   

  1)List接口

   List接口對Collection進行了簡單的擴充

   查看List接口的源碼會發現:

   

12345678910111213...<br> * @see AbstractList @see AbstractSequentialList @since 1.2 */ public interface List<E> extends Collection<E> {    // Query Operations     /**     * Returns the number of elements in this list.  If this list contains     * more than <tt>Integer.MAX_VALUE</tt> elements, returns     * <tt>Integer.MAX_VALUE</tt>.<br>   ...

  這里也就知道為什么Collection接口時List接口的父接口了吧。

  List接口中的元素的特點為:

  List中存儲的元素實現類排序,而且可以重復的存儲相關元素。

 

  同時List接口又有兩個常用的實現類ArrayList和LinkedList

    1)ArrayList:

      ArrayList數組線性表的特點為:類似數組的形式進行存儲,因此它的隨機訪問速度極快。

      ArrayList數組線性表的缺點為:不適合于在線性表中間需要頻繁進行插入和刪除操作。因為每次插入和刪除都需要移動數組中的元素。

 

      可以這樣理解ArrayList就是基于數組的一個線性表,只不過數組的長度可以動態改變而已。

      對于ArrayList的詳細使用信息以及創建的過程可以查看jdk中ArrayList的源碼,這里不做過多的講解。 

      對于使用ArrayList的開發者而言,下面幾點內容一定要注意啦,尤其找工作面試的時候經常會被問到。

      注意啦?。。。。。。。?/p>

      a.如果在初始化ArrayList的時候沒有指定初始化長度的話,默認的長度為10.    

      

123456/**     * Constructs an empty list with an initial capacity of ten.     */    public ArrayList() {    this(10);    }

 

 

      b.ArrayList在增加新元素的時候如果超過了原始的容量的話,ArrayList擴容ensureCapacity的方案為“原始容量*3/2+1"哦。

     

12345678910111213141516171819/** * Increases the capacity of this <tt>ArrayList</tt> instance, if * necessary, to ensure that it can hold at least the number of elements * specified by the minimum capacity argument. * * @param   minCapacity   the desired minimum capacity */public void ensureCapacity(int minCapacity) {modCount++;int oldCapacity = elementData.length;if (minCapacity > oldCapacity) {    Object oldData[] = elementData;    int newCapacity = (oldCapacity * 3)/2 1;        if (newCapacity < minCapacity)    newCapacity = minCapacity;        // minCapacity is usually close to size, so this is a win:        elementData = Arrays.copyOf(elementData, newCapacity);}}

 

    c.ArrayList是線程不安全的,在多線程的情況下不要使用。

          如果一定在多線程使用List的,您可以使用Vector,因為Vector和ArrayList基本一致,區別在于Vector中的絕大部分方法都

          使用了同步關鍵字修飾,這樣在多線程的情況下不會出現并發錯誤哦,還有就是它們的擴容方案不同,ArrayList是通過原始

         容量*3/2+1,而Vector是允許設置默認的增長長度,Vector的默認擴容方式為原來的2倍。

         切記Vector是ArrayList的多線程的一個替代品。

       d.ArrayList實現遍歷的幾種方法

         

1234567891011121314151617181920212223242526272829303132333435363738394041package com.yonyou.test; import java.util.ArrayList;import java.util.Iterator;import java.util.List;  /** * 測試類 * @author 小浩 * @創建日期 2015-3-2 */ public class Test{public static void main(String[] args) {     List<String> list=new ArrayList<String>();     list.add("Hello");     list.add("World");     list.add("HAHAHAHA");     //第一種遍歷方法使用foreach遍歷List     for (String str : list) {            //也可以改寫for(int i=0;i<list.size();i++)這種形式        System.out.PRintln(str);    }      //第二種遍歷,把鏈表變為數組相關的內容進行遍歷    String[] strArray=new String[list.size()];    list.toArray(strArray);    for(int i=0;i<strArray.length;i++) //這里也可以改寫為foreach(String str:strArray)這種形式    {        System.out.println(strArray[i]);    }         //第三種遍歷 使用迭代器進行相關遍歷          Iterator<String> ite=list.iterator();     while(ite.hasNext())     {         System.out.println(ite.next());     } }}

 

  

 

          尼瑪,以上四點面試經常會被問到的。到時候死翹翹別說哥沒告訴你。

 

    2)LinkedList

       LinkedList的鏈式線性表的特點為: 適合于在鏈表中間需要頻繁進行插入和刪除操作。

       LinkedList的鏈式線性表的缺點為: 隨機訪問速度較慢。查找一個元素需要從頭開始一個一個的找。速度你懂的。

 

      可以這樣理解LinkedList就是一種雙向循環鏈表的鏈式線性表,只不過存儲的結構使用的是鏈式表而已。

      對于LinkedList的詳細使用信息以及創建的過程可以查看jdk中LinkedList的源碼,這里不做過多的講解。

      對于使用LinkedList的開發者而言,下面幾點內容一定要注意啦,尤其找工作面試的過程時候經常會被問到。

      注意啦?。。。。。。?!

      

      a.LinkedList和ArrayList的區別和聯系

      ArrayList數組線性表的特點為:類似數組的形式進行存儲,因此它的隨機訪問速度極快。

      ArrayList數組線性表的缺點為:不適合于在線性表中間需要頻繁進行插入和刪除操作。因為每次插入和刪除都需要移動數組中的元素。

 

       LinkedList的鏈式線性表的特點為: 適合于在鏈表中間需要頻繁進行插入和刪除操作。

       LinkedList的鏈式線性表的缺點為: 隨機訪問速度較慢。查找一個元素需要從頭開始一個一個的找。速度你懂的。

    

      b.LinkedList的內部實現

         對于這個問題,你最好看一下jdk中LinkedList的源碼。這樣你會醍醐灌頂的。

         這里我大致說一下:

         LinkedList的內部是基于雙向循環鏈表的結構來實現的。在LinkedList中有一個類似于c語言中結構體的Entry內部類。

         在Entry的內部類中包含了前一個元素的地址引用和后一個元素的地址引用類似于c語言中指針。

     c.LinkedList不是線程安全的

         注意LinkedList和ArrayList一樣也不是線程安全的,如果在對線程下面訪問可以自己重寫LinkedList

         然后在需要同步的方法上面加上同步關鍵字synchronized

     d.LinkedList的遍歷方法

       

123456789101112131415161718192021222324252627282930313233343536package com.yonyou.test; import java.util.LinkedList;import java.util.List;  /** * 測試類 * @author 小浩 * @創建日期 2015-3-2 */ public class Test{public static void main(String[] args) {         List<String> list=new LinkedList<String>();    list.add("Hello");    list.add("World");    list.add("龍不吟,虎不嘯");    //LinkedList遍歷的第一種方式使用數組的方式    String[] strArray=new String[list.size()];    list.toArray(strArray);    for(String str:strArray)    {        System.out.println(str);    }    //LinkedList遍歷的第二種方式    for(String str:list)    {        System.out.println(str);       }    //至于還是否有其它遍歷方式,我沒查,感興趣自己研究研究                }}

      e.LinkedList可以被當做堆棧來使用

        由于LinkedList實現了接口Dueue,所以LinkedList可以被當做堆棧來使用,這個你自己研究吧。

 

 

  2)Set接口

     Set接口也是Collection接口的一個常用子接口。

     查看Set接口的源碼你會發現:

   

12345678910@see Collections#EMPTY_SET @since 1.2 */ public interface Set<E> extends Collection<E> {    // Query Operations     /**     * Returns the number of elements in this set (its cardinality).  If this     * set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns

   這里就自然而然的知道Set接口是Collection接口的子接口了吧。

   Set接口區別于List接口的特點在于:

   Set中的元素實現了不重復,有點象集合的概念,無序,不允許有重復的元素,最多允許有一個null元素對象。

   需要注意的是:雖然Set中元素沒有順序,但是元素在set中的位置是有由該元素的HashCode決定的,其具體位置其實是固定的。

   查看jdk的源碼會發現下面的內容

  

1234567891011...<br> * @see Collections#EMPTY_SET @since 1.2 */ public interface Set<E> extends Collection<E> {    // Query Operations     /**     * Returns the number of elements in this set (its cardinality).  If this     * set contains more than <tt>Integer.MAX_VALUE</tt> elements, returns<br> ...

    在這里也會看到set接口時Collection接口的子接口吧~哈

   此外需要說明一點,在set接口中的不重復是由特殊要求的。

    舉一個例子:對象A和對象B,本來是不同的兩個對象,正常情況下它們是能夠放入到Set里面的,但是

    如果對象A和B的都重寫了hashcode和equals方法,并且重寫后的hashcode和equals方法是相同的話。那么A和B是不能同時放入到

    Set集合中去的,也就是Set集合中的去重和hashcode與equals方法直接相關。

    為了更好的理解,請看下面的例子:

   

12345678910111213141516171819202122package com.yonyou.test; import java.util.HashSet;import java.util.Set;  /** * 測試類 * @author 小浩 * @創建日期 2015-3-2 */ public class Test{public static void main(String[] args) {     Set<String> set=new HashSet<String>();     set.add("Hello");     set.add("world");     set.add("Hello");     System.out.println("集合的尺寸為:"+set.size());     System.out.println("集合中的元素為:"+set.toString());  }}

  由于String類中重寫了hashcode和equals方法,所以這里的第二個Hello是加不進去的哦。

  

 

    Set接口的常見實現類有HashSet,LinedHashSet和TreeSet這三個。下面我們將分別講解這三個類。

      1)HashSet

         HashSet是Set接口的最常見的實現類了。其底層是基于Hash算法進行存儲相關元素的。

         下面是HashSet的部分源碼:

        

1234567/**    * Constructs a new, empty set; the backing <tt>HashMap</tt> instance has    * default initial capacity (16) and load factor (0.75).    */   public HashSet() {   map = new HashMap<E,Object>();   }

   你看到了什么,沒錯,對于HashSet的底層就是基于HashMap來實現的哦。

   我們都知道在HashMap中的key是不允許重復的,你換個角度看看,那不就是說Set集合嗎?

   這里唯一一個需要處理的就是那個Map的value弄成一個固定值即可。

   看來一切水到渠成啊~哈哈~這里的就是Map中的Key。

   對于HashMap和Hash算法的講解會在下面出現,先別著急,下面繼續講解HashSet。

  

    下面講解一下HashSet使用和理解中容易出現的誤區:

     a.HashSet中存放null值

        HashSet中時允許出入null值的,但是在HashSet中僅僅能夠存入一個null值哦。

     b.HashSet中存儲元素的位置是固定的

        HashSet中存儲的元素的是無序的,這個沒什么好說的,但是由于HashSet底層是基于Hash算法實現的,使用了hashcode,

        所以HashSet中相應的元素的位置是固定的哦。

     c.遍歷HashSet的幾種方法

         具體的方法不說了,請看下面的代碼:

      

12345678910111213141516171819202122232425262728293031323334353637383940package com.yonyou.test; import java.util.HashSet;import java.util.Iterator;import java.util.Set;  /** * 測試類 * @author 小浩 * @創建日期 2015-3-2 */ public class Test{public static void main(String[] args) {     Set<String> set=new HashSet<String>();     set.add("Hello");     set.add("world");     set.add("Hello");     //遍歷集合的第一種方法,使用數組的方法     String[] strArray=new String[set.size()];     strArray=set.toArray(strArray);     for(String str:strArray)//此處也可以使用for(int i=0;i<strArray.length;i++)     {         System.out.println(str);     }     //遍歷集合的第二中方法,使用set集合直接遍歷     for(String str:set)     {         System.out.println(str);     }           //遍歷集合的第三種方法,使用iterator迭代器的方法     Iterator<String> iterator=set.iterator();     while(iterator.hasNext())     {         System.out.println(iterator.next());     }}}

     2)LinkHashSet

       LinkHashSet不僅是Set接口的子接口而且還是上面HashSet接口的子接口。

       查看LinkedHashSet的部分源碼如下:

      

12345678910111213...<br> * @see     Hashtable @since   1.4 */ public class LinkedHashSet<E>    extends HashSet<E>    implements Set<E>, Cloneable, java.io.Serializable {     private static final long serialVersionUID = -2851667679971038690L;     /**     * Constructs a new, empty linked hash set with the specified initial<br>  ...

     這里就可以發現Set接口時HashSet接口的一個子接口了吧~

     通過查看LinkedHashSet的源碼可以發現,其底層是基于LinkedHashMap來實現的哦。

     對于LinkedHashSet而言,它和HashSet主要區別在于LinkedHashSet中存儲的元素是在哈希算法的基礎上增加了

     鏈式表的結構。

    

    3)TreeSet

       TreeSet是一種排序二叉樹。存入Set集合中的值,會按照值的大小進行相關的排序操作。底層算法是基于紅黑樹來實現的。

       TreeSet和HashSet的主要區別在于TreeSet中的元素會按照相關的值進行排序~

       TreeSet和HashSet的區別和聯系

       1. HashSet是通過HashMap實現的,TreeSet是通過TreeMap實現的,只不過Set用的只是Map的key       2. Map的key和Set都有一個共同的特性就是集合的唯一性.TreeMap更是多了一個排序的功能.       3. hashCode和equal()是HashMap用的, 因為無需排序所以只需要關注定位和唯一性即可.           a. hashCode是用來計算hash值的,hash值是用來確定hash表索引的.           b. hash表中的一個索引處存放的是一張鏈表, 所以還要通過equal方法循環比較鏈上的每一個對象              才可以真正定位到鍵值對應的Entry.           c. put時,如果hash表中沒定位到,就在鏈表前加一個Entry,如果定位到了,則更換Entry中的value,并返回舊value       4. 由于TreeMap需要排序,所以需要一個Comparator為鍵值進行大小比較.當然也是用Comparator定位的.           a. Comparator可以在創建TreeMap時指定           b. 如果創建時沒有確定,那么就會使用key.compareTo()方法,這就要求key必須實現Comparable接口.           c. TreeMap是使用Tree數據結構實現的,所以使用compare接口就可以完成定位了.

         下面是一個使用TreeSet的實例:

 

123456789101112131415161718192021222324252627package com.yonyou.test; import java.util.Iterator;import java.util.TreeSet; /** * TreeSet測試類 * @author 小浩 * @創建日期 2015-4-3 */public class Test{    public static void main(String[] args) {        //String實體類中實現Comparable接口,所以在初始化TreeSet的時候,        //無需傳入比較器        TreeSet<String> treeSet=new TreeSet<String>();        treeSet.add("d");        treeSet.add("c");        treeSet.add("b");        treeSet.add("a");        Iterator<String> iterator=treeSet.iterator();        while(iterator.hasNext())        {            System.out.println(iterator.next());        }              }}

 

 3)Map接口

      說到Map接口的話大家也許在熟悉不過了。Map接口實現的是一組Key-Value的鍵值對的組合。 Map中的每個成員方法由一個關鍵字(key)和一個值(value)構成。Map接口不直接繼承于Collection接口(需要注意啦),因為它包裝的是一組成對的“鍵-值”對象的集合,而且在Map接口的集合中也不能有重復的key出現,因為每個鍵只能與一個成員元素相對應。在我們的日常的開發項目中,我們無時無刻不在使用者Map接口及其實現類。Map有兩種比較常用的實現:HashMap和TreeMap等。HashMap也用到了哈希碼的算法,以便快速查找一個鍵,TreeMap則是對鍵按序存放,因此它便有一些擴展的方法,比如firstKey(),lastKey()等,你還可以從TreeMap中指定一個范圍以取得其子Map。鍵和值的關聯很簡單,用pub(Object key,Object value)方法即可將一個鍵與一個值對象相關聯。用get(Object key)可得到與此key對象所對應的值對象。

       另外前邊已經說明了,Set接口的底層是基于Map接口實現的。Set中存儲的值,其實就是Map中的key,它們都是不允許重復的。

      Map接口的部分源碼如下:

     

123456789@see Collection @see Set @since 1.2 */public interface Map<K,V> {    // Query Operations     /**     * Returns the number of key-value mappings in this map.  If the

  

      為了更好的理解上面的內容,這里我們有必要簡單了解一下Hash算法的內容,由于篇幅限制,這里就不具體的講解Hash算法的實現過程了。如果感興趣的可以參考:http://www.cnblogs.com/xiohao/p/4389672.html

      接下來我們講解Map接口的常見實現類HashMap、TreeMap、LinkedHashMap、Properties(繼承HashTable)以及老版本的HashTable等。

      3)HashMap

       HashMap實現了Map、CloneMap、Serializable三個接口,并且繼承自AbstractMap類。

         HashMap基于hash數組實現,若key的hash值相同則使用鏈表方式進行保存。

   

     

    

      新建一個HashMap時,默認的話會初始化一個大小為16,負載因子為0.75的空的HashMap

12345678910/**     * Constructs an empty <tt>HashMap</tt> with the default initial capacity     * (16) and the default load factor (0.75).     */    public HashMap() {        this.loadFactor = DEFAULT_LOAD_FACTOR;        threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);        table = new Entry[DEFAULT_INITIAL_CAPACITY];        init();    }

   下面是一個HashMap中還存在一個內部類Entry,用于鏈表的存儲,如

  

1static class Entry<K,V> implements Map.Entry<K,V> {<br>      final K key;<br>      V value;<br>      Entry<K,V> next;<br>      final int hash;<br>      ......

 

  面代碼其實告訴我們Entry是一個結點,它持有下一個元素的引用,這樣就構成了一個鏈表。

那么,整體上來說HashMap底層就是使用這樣一個數據結構來實現的。

我們提到使用Hash,但是Hash值如何與元素的存儲建立關系呢?(Hash算法)

在數據結構課中我們學習過Hash的簡單算法,就是給你一個Hash因子,通過對該元素的hashCode簡單的求余,來實現對其快速的定位和索引。

在HashMap中有這樣的代碼:

/**  * Returns index for hash code h.  */ static int indexFor(int h, int length) {      return h & (length-1); } 
/**  * Returns index for hash code h.  */static int indexFor(int h, int length) {     return h & (length-1);}

這個方法在HashMap中非常重要,凡是與查詢、添加、刪除有關的方法中都有調用該方法,為什么這么短的一個代碼使用率這么高?根據代碼注釋我們知道,這個方法是根據hashCode及當前table的長度(數組的長度,不是map的size)得到該元素應該存放的位置,或者在table中的索引。

現在我們需要看一下當數據量已經超過初始定義的負載因子時,HashMap如何處理?

在HashMap中當數據量很多時,并且已經達到了負載限度時,會重新做一次哈希,也就是說會再散列。調用的方法為resize(),并且java默認傳入的參數為2*table.length。先看一下JDK源碼:

/**     * Rehashes the contents of this map into a new array with a     * larger capacity.  This method is called automatically when the     * number of keys in this map reaches its threshold.     *     * If current capacity is MAXIMUM_CAPACITY, this method does not     * resize the map, but sets threshold to Integer.MAX_VALUE.     * This has the effect of preventing future calls.     *     * @param newCapacity the new capacity, MUST be a power of two;     *        must be greater than current capacity unless current     *        capacity is MAXIMUM_CAPACITY (in which case value     *        is irrelevant).     */     void resize(int newCapacity) {         Entry[] oldTable = table;         int oldCapacity = oldTable.length;         if (oldCapacity == MAXIMUM_CAPACITY) {             threshold = Integer.MAX_VALUE;             return;         }          Entry[] newTable = new Entry[newCapacity];         transfer(newTable);         table = newTable;         threshold = (int)(newCapacity * loadFactor);     }      /**     * Transfers all entries from current table to newTable.     */     void transfer(Entry[] newTable) {         Entry[] src = table;         int newCapacity = newTable.length;         for (int j = 0; j < src.length; j++) {             Entry<K,V> e = src[j];             if (e != null) {                 src[j] = null;                 do {                     Entry<K,V> next = e.next;                     int i = indexFor(e.hash, newCapacity);                     e.next = newTable[i];                     newTable[i] = e;                     e = next;                 } while (e != null);             }         }     } 
 

看到這里我們會發現resize(再哈希)的工作量是不是很大啊。再哈希是重新建一個指定容量的數組,然后將每個元素重新計算它要放的位置,這個工作量確實是很大的。

這里就產生了一個很重要的問題,那就是怎么讓哈希表的分布比較均勻,也就是說怎么讓它即不會成為一個單鏈表(極限情況,每個key的hash值都集中到了一起),又不會使hash空間過大(導致內存浪費)?

上面兩個問題一個是解決了怎么計算hash值快速存取,一個是怎么實現再哈希,何時需要再哈希??焖俅嫒〉那疤崾窃胤植季鶆颍恢劣诩械揭稽c,再哈希是元素過于零散,導致不斷的重新構建表。

那么在第一個問題中我們看到了這樣一個代碼return h & (length-1);在第二個問題中我們說過內部調用傳入的值為2*table.length;并且默認情況下HashMap的大小為一個16的數字,除了默認構造提供大小為16的空間外,如果我們使用

public HashMap(int initialCapacity, float loadFactor)

上面的構造方法,我們會發現這樣的代碼:

// Find a power of 2 >= initialCapacity int capacity = 1; while (capacity < initialCapacity)       capacity <<= 1; …… table = new Entry[capacity]; 
// Find a power of 2 >= initialCapacityint capacity = 1;while (capacity < initialCapacity)      capacity <<= 1;……table = new Entry[capacity];

也就是說當我們傳入1000時,它并沒有給我們構造一個容量為1000的哈希表,而是構建了一個容量為1024大小的哈希表。

從整體上我們發現一個問題,那就是無論什么情況HashMap中哈希表的容量總是2的n次方的一個數。并且有這樣一個公式:

       當length=2^n時,hashcode & (length-1) == hashcode % length

也就是這一點驗證了第一個問題,hash索引值的計算方法其實就是對哈希因子求余。只有大小為2的n次方時,那樣的計算才成立,所以HashMap為我們維護了一個這樣大小的一個哈希表。(位運算速度比取模運算快的多)

c)      HashMap的使用方法:

我在很多代碼中都用到了HashMap,原因是首先它符合存儲關聯數據的要求,其次它的存取速度快,這是一個選擇的問題。

比較重要的是HashMap的遍歷方法,在我的博客中有專門寫到HashMap的遍歷方法:http://blog.csdn.net/tsyj810883979/article/details/6746274

?  LinkedHashMap的特點、實現機制及使用方法

a)      LinkedHashMap的特點:

LinkedHashMap繼承自HashMap并且實現了Map接口。和HashMap一樣,LinkedHashMap允許key和value均為null。

于該數據結構和HashMap一樣使用到hash算法,因此它不能保證映射的順序,尤其是不能保證順序持久不變(再哈希)。

如果你想在多線程中使用,那么需要使用Collections.synchronizedMap方法進行外部同步。

LinkedHashMap與HashMap的不同之處在于,LinkedHashMap維護者運行于所有條目的雙重鏈接列表,此鏈接列表可以是插入順序或者訪問順序。

b)      LinkedHashMap的實現機制:

無法總結下去,在網上看到這樣一篇文章:http://zhangshixi.iteye.com/blog/673789

感覺真的沒辦法總結下去了。

?  HashMap與Hashtable的區別:

Hashtable實現Map接口,繼承自古老的Dictionary類,實現一個key-value的鍵值映射表。任何非空的(key-value)均可以放入其中。

區別主要有三點:

1.      Hashtable是基于陳舊的Dictionary實現的,而HashMap是基于Java1.2引進的Map接口實現的;

2.      Hashtable是線程安全的,而HashMap是非線程安全的,我們可以使用外部同步的方法解決這個問題。

3.      HashMap可以允許你在列表中放一個key值為null的元素,并且可以有任意多value為null,而Hashtable不允許鍵或者值為null。

?  WeakHashMap的特點:

我沒有使用過這個類。網摘:WeakHashMap是一種改進的HashMap,它對key實行“弱引用”,如果一個key不再被外部所引用,那么該key可以被GC回收。(后續使用后進行總結)

?  Properties及TreeMap在后續內容里進行總結。

 

就先這樣吧,Java集合框架的講解就先到這里了啊~

學習Java的同學注意了?。?! 學習過程中遇到什么問題或者想獲取學習資源的話,歡迎加入Java學習交流群,群號碼:523047986  我們一起學Java!


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
欧美激情一级欧美精品| 91在线精品播放| 亚洲激情视频网站| 伊人亚洲福利一区二区三区| 日本午夜人人精品| 欧美亚洲免费电影| 欧美一级片一区| 亚洲成人久久电影| 成人av电影天堂| 日韩中文字幕在线视频| 欧美有码在线视频| 欧美性猛交丰臀xxxxx网站| 欧美日韩亚洲91| 午夜精品福利视频| 国产精品高精视频免费| 精品久久久久久中文字幕一区奶水| 亚洲欧美精品伊人久久| 国产精品亚洲网站| 欧美成人一区二区三区电影| 成人xvideos免费视频| 亚洲欧美国产日韩中文字幕| 亚洲精品之草原avav久久| 欧美高清视频免费观看| 日韩中文字幕在线观看| 日韩在线免费视频观看| 欧美猛少妇色xxxxx| 国产精品成av人在线视午夜片| 欧美成人精品在线| 日韩女在线观看| 国内精品视频久久| 国产成人精品在线视频| 亚洲国产精彩中文乱码av在线播放| 91免费人成网站在线观看18| 国产精品成人久久久久| 夜夜嗨av一区二区三区免费区| 精品偷拍各种wc美女嘘嘘| 欧美交受高潮1| 亚洲天堂开心观看| 久久久精品国产| 亚洲小视频在线| 国产精品视频资源| 亚洲在线一区二区| 日韩精品中文字幕在线观看| 97视频在线观看免费高清完整版在线观看| 一区二区在线免费视频| 国产精品福利网| 亚洲va欧美va国产综合久久| 国产日韩在线一区| 色综合亚洲精品激情狠狠| xvideos成人免费中文版| 亲爱的老师9免费观看全集电视剧| 久久久www成人免费精品张筱雨| 91sa在线看| 国内精品一区二区三区四区| 亚洲综合第一页| 国产精品久久久91| 亚洲欧美中文日韩在线| 亚洲一区二区三区视频| 911国产网站尤物在线观看| 国产国产精品人在线视| 国内精品伊人久久| 91在线精品播放| 国产精自产拍久久久久久蜜| 欧美性xxxxxx| 国产日韩欧美在线| 国产精品一香蕉国产线看观看| 亚洲字幕一区二区| 91国产精品91| 欧美精品久久久久久久久| 久久精品国产精品亚洲| 亚洲一区精品电影| 亚洲欧美日韩中文视频| 亚洲成人久久久久| 国自产精品手机在线观看视频| 日韩欧美国产黄色| 欧美黑人巨大精品一区二区| 国产精品看片资源| 欧美色播在线播放| 久久久www成人免费精品张筱雨| 欧美日韩一区免费| 欧美刺激性大交免费视频| 欧美电影院免费观看| 另类天堂视频在线观看| 欧美日韩亚洲精品一区二区三区| 欧美成人中文字幕| 亚洲欧美一区二区三区四区| 九九九久久国产免费| 国产成人精品在线播放| 国产欧美一区二区| 久久人人爽人人爽人人片av高清| 91国语精品自产拍在线观看性色| 日韩成人在线免费观看| 久久精品国产v日韩v亚洲| 国产日韩中文在线| 国产91在线高潮白浆在线观看| 97在线视频一区| 色诱女教师一区二区三区| 欧美美女15p| 久久成人av网站| 亚洲图片欧洲图片av| 精品久久久久久久久国产字幕| 欧美精品在线免费| 日韩精品丝袜在线| 久久久久北条麻妃免费看| 亚洲精品mp4| 午夜精品一区二区三区在线播放| 日韩免费电影在线观看| 性色av香蕉一区二区| 国内揄拍国内精品少妇国语| 国产不卡av在线免费观看| 欧美在线性爱视频| 最近中文字幕2019免费| 久久久久久国产精品三级玉女聊斋| 国产又爽又黄的激情精品视频| 亚洲午夜久久久久久久| 欧亚精品在线观看| 久久久久久久av| 最新国产精品拍自在线播放| 亚洲男人天堂2019| 中文字幕精品久久| 精品一区二区亚洲| 8090理伦午夜在线电影| 日韩av在线网址| 久久久久久久久久久91| 日韩va亚洲va欧洲va国产| 国产成人综合久久| 色噜噜狠狠狠综合曰曰曰| 欧美裸体xxxx| 成人女保姆的销魂服务| 91国内免费在线视频| 久久视频国产精品免费视频在线| 国产精品久久久久久久av大片| 亚洲国产成人精品久久| 欧美成人中文字幕在线| 久久久精品日本| 亚洲欧洲国产精品| 国产有码一区二区| 中日韩午夜理伦电影免费| 国产日韩欧美视频在线| 欧美日韩亚洲一区二| 欧美视频国产精品| 国产精品视频一区国模私拍| 久久久久久久av| 精品国产一区二区三区久久狼黑人| 日韩av影院在线观看| 懂色av影视一区二区三区| 久久精品国产69国产精品亚洲| 亚洲精品国产精品自产a区红杏吧| 国产精品男女猛烈高潮激情| 一个色综合导航| 日韩在线视频观看正片免费网站| 96sao精品视频在线观看| 日韩欧美中文字幕在线播放| 欧美色欧美亚洲高清在线视频| 国产精品综合久久久| 亚洲国产成人91精品| 亚洲自拍偷拍第一页| 尤物99国产成人精品视频| 国产精品夫妻激情| 久久久久中文字幕| 欧美在线视频播放| 日韩欧美国产骚| 911国产网站尤物在线观看| 欧美精品激情视频|