欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

JAVA集合框架專題

 更新時(shí)間:2020年06月16日 16:35:18   作者:冰湖一角  
這篇文章主要介紹了JAVA集合框架的相關(guān)知識(shí),文中講解非常細(xì)致,幫助大家更好的理解學(xué)習(xí)JAVA框架,感興趣的朋友快來(lái)了解下

一、Java集合框架概述

  集合可以看作是一種容器,用來(lái)存儲(chǔ)對(duì)象信息。所有集合類都位于java.util包下,但支持多線程的集合類位于java.util.concurrent包下。

  數(shù)組與集合的區(qū)別如下:

 ?。?)數(shù)組長(zhǎng)度不可變化而且無(wú)法保存具有映射關(guān)系的數(shù)據(jù);集合類用于保存數(shù)量不確定的數(shù)據(jù),以及保存具有映射關(guān)系的數(shù)據(jù)。

 ?。?)數(shù)組元素既可以是基本類型的值,也可以是對(duì)象;集合只能保存對(duì)象。

  Java集合類主要由兩個(gè)根接口Collection和Map派生出來(lái)的,Collection派生出了三個(gè)子接口:List、Set、Queue(Java5新增的隊(duì)列),因此Java集合大致也可分成List、Set、Queue、Map四種接口體系,(注意:Map不是Collection的子接口)。

  其中List代表了有序可重復(fù)集合,可直接根據(jù)元素的索引來(lái)訪問(wèn);Set代表無(wú)序不可重復(fù)集合,只能根據(jù)元素本身來(lái)訪問(wèn);Queue是隊(duì)列集合;Map代表的是存儲(chǔ)key-value對(duì)的集合,可根據(jù)元素的key來(lái)訪問(wèn)value。

  上圖中淡綠色背景覆蓋的是集合體系中常用的實(shí)現(xiàn)類,分別是ArrayList、LinkedList、ArrayQueue、HashSet、TreeSet、HashMap、TreeMap等實(shí)現(xiàn)類。

二、Java集合常見接口及實(shí)現(xiàn)類

1. Collection接口常見方法(來(lái)源于Java API)

2. Set集合

   Set集合與Collection的方法相同,由于Set集合不允許存儲(chǔ)相同的元素,所以如果把兩個(gè)相同元素添加到同一個(gè)Set集合,則添加操作失敗,新元素不會(huì)被加入,add()方法返回false。為了幫助理解,請(qǐng)看下面代碼示例:

public class Test {

  public static void main(String[] args) {
    Set<String> set = new HashSet<String>();
    set.add("hello world");
    set.add("hello 冰湖一角");
    set.add("hello 冰湖一角");//添加不進(jìn)去
    System.out.println("集合中元素個(gè)數(shù):"+set.size());
    System.out.println("集合中元素為:"+set.toString());
  }
}

運(yùn)行結(jié)果如下:

集合中元素個(gè)數(shù):2
集合中元素為:[hello world, hello 冰湖一角]

分析:由于String類中重寫了hashCode()和equals()方法,用來(lái)比較指向的字符串對(duì)象所存儲(chǔ)的字符串是否相等。所以這里的第二個(gè)"hello 冰湖一角"是加不進(jìn)去的。

下面著重介紹Set集合幾個(gè)常用實(shí)現(xiàn)類:

(1)HashSet類

  HashSet是Set集合最常用實(shí)現(xiàn)類,是其經(jīng)典實(shí)現(xiàn)。HashSet是按照hash算法來(lái)存儲(chǔ)元素的,因此具有很好的存取和查找性能。

  HashSet具有如下特點(diǎn):

  • 不能保證元素的順序。
  • HashSet不是線程同步的,如果多線程操作HashSet集合,則應(yīng)通過(guò)代碼來(lái)保證其同步。
  • 集合元素值可以是null。

  HashSet存儲(chǔ)原理如下:

  當(dāng)向HashSet集合存儲(chǔ)一個(gè)元素時(shí),HashSet會(huì)調(diào)用該對(duì)象的hashCode()方法得到其hashCode值,然后根據(jù)hashCode值決定該對(duì)象的存儲(chǔ)位置。HashSet集合判斷兩個(gè)元素相等的標(biāo)準(zhǔn)是(1)兩個(gè)對(duì)象通過(guò)equals()方法比較返回true;(2)兩個(gè)對(duì)象的hashCode()方法返回值相等。因此,如果(1)和(2)有一個(gè)不滿足條件,則認(rèn)為這兩個(gè)對(duì)象不相等,可以添加成功。如果兩個(gè)對(duì)象的hashCode()方法返回值相等,但是兩個(gè)對(duì)象通過(guò)equals()方法比較返回false,HashSet會(huì)以鏈?zhǔn)浇Y(jié)構(gòu)將兩個(gè)對(duì)象保存在同一位置,這將導(dǎo)致性能下降,因此在編碼時(shí)應(yīng)避免出現(xiàn)這種情況。

  HashSet查找原理如下:

  基于HashSet以上的存儲(chǔ)原理,在查找元素時(shí),HashSet先計(jì)算元素的HashCode值(也就是調(diào)用對(duì)象的hashCode方法的返回值),然后直接到hashCode值對(duì)應(yīng)的位置去取出元素即可,這就是HashSet速度很快的原因。

   重寫hashCode()方法的基本原則如下:

  • 在程序運(yùn)行過(guò)程中,同一個(gè)對(duì)象的hashCode()方法返回值應(yīng)相同。
  • 當(dāng)兩個(gè)對(duì)象通過(guò)equals()方法比較返回true時(shí),這兩個(gè)對(duì)象的hashCode()方法返回值應(yīng)該相等。
  • 對(duì)象中用作equals()方法比較標(biāo)準(zhǔn)的實(shí)例變量,都應(yīng)該用于計(jì)算hashCode值。

(2)LinkedHashSet類

   LinkedHashSet是HashSet的一個(gè)子類,具有HashSet的特性,也是根據(jù)元素的hashCode值來(lái)決定元素的存儲(chǔ)位置。但它使用鏈表維護(hù)元素的次序,元素的順序與添加順序一致。由于LinkedHashSet需要維護(hù)元素的插入順序,因此性能略低于HashSet,但在迭代訪問(wèn)Set里的全部元素時(shí)由很好的性能。

(3)TreeSet類

  TreeSet時(shí)SortedSet接口的實(shí)現(xiàn)類,TreeSet可以保證元素處于排序狀態(tài),它采用紅黑樹的數(shù)據(jù)結(jié)構(gòu)來(lái)存儲(chǔ)集合元素。TreeSet支持兩種排序方法:自然排序和定制排序,默認(rèn)采用自然排序。

  • 自然排序

  TreeSet會(huì)調(diào)用集合元素的compareTo(Object obj)方法來(lái)比較元素的大小關(guān)系,然后將元素按照升序排列,這就是自然排序。如果試圖將一個(gè)對(duì)象添加到TreeSet集合中,則該對(duì)象必須實(shí)現(xiàn)Comparable接口,否則會(huì)拋出異常。當(dāng)一個(gè)對(duì)象調(diào)用方法與另一個(gè)對(duì)象比較時(shí),例如obj1.compareTo(obj2),如果該方法返回0,則兩個(gè)對(duì)象相等;如果返回一個(gè)正數(shù),則obj1大于obj2;如果返回一個(gè)負(fù)數(shù),則obj1小于obj2。

  Java常用類中已經(jīng)實(shí)現(xiàn)了Comparable接口的類有以下幾個(gè):

  1. BigDecimal、BigDecimal以及所有數(shù)值型對(duì)應(yīng)的包裝類:按照它們對(duì)應(yīng)的數(shù)值大小進(jìn)行比較。
  2. Charchter:按照字符的unicode值進(jìn)行比較。
  3. Boolean:true對(duì)應(yīng)的包裝類實(shí)例大于false對(duì)應(yīng)的包裝類實(shí)例。
  4. String:按照字符串中的字符的unicode值進(jìn)行比較。
  5. Date、Time:后面的時(shí)間、日期比前面的時(shí)間、日期大。

  對(duì)于TreeSet集合而言,它判斷兩個(gè)對(duì)象是否相等的標(biāo)準(zhǔn)是:兩個(gè)對(duì)象通過(guò)compareTo(Object obj)方法比較是否返回0,如果返回0則相等。

  • 定制排序

  想要實(shí)現(xiàn)定制排序,需要在創(chuàng)建TreeSet集合對(duì)象時(shí),提供一個(gè)Comparator對(duì)象與該TreeSet集合關(guān)聯(lián),由Comparator對(duì)象負(fù)責(zé)集合元素的排序邏輯。

  綜上:自然排序?qū)崿F(xiàn)的是Comparable接口,定制排序?qū)崿F(xiàn)的是Comparator接口。(具體代碼實(shí)現(xiàn)會(huì)在后續(xù)章節(jié)中講解)

(4)EnumSet類

  EnumSet是一個(gè)專為枚舉類設(shè)計(jì)的集合類,不允許添加null值。EnumSet的集合元素也是有序的,它以枚舉值在Enum類內(nèi)的定義順序來(lái)決定集合元素的順序。

(5)各Set實(shí)現(xiàn)類的性能分析

  HashSet的性能比TreeSet的性能好(特別是添加,查詢?cè)貢r(shí)),因?yàn)門reeSet需要額外的紅黑樹算法維護(hù)元素的次序,如果需要一個(gè)保持排序的Set時(shí)才用TreeSet,否則應(yīng)該使用HashSet。

  LinkedHashSet是HashSet的子類,由于需要鏈表維護(hù)元素的順序,所以插入和刪除操作比HashSet要慢,但遍歷比HashSet快。

  EnumSet是所有Set實(shí)現(xiàn)類中性能最好的,但它只能 保存同一個(gè)枚舉類的枚舉值作為集合元素。

  以上幾個(gè)Set實(shí)現(xiàn)類都是線程不安全的,如果多線程訪問(wèn),必須手動(dòng)保證集合的同步性,這在后面的章節(jié)中會(huì)講到。

3. List集合

  List集合代表一個(gè)有序、可重復(fù)集合,集合中每個(gè)元素都有其對(duì)應(yīng)的順序索引。List集合默認(rèn)按照元素的添加順序設(shè)置元素的索引,可以通過(guò)索引(類似數(shù)組的下標(biāo))來(lái)訪問(wèn)指定位置的集合元素。

  實(shí)現(xiàn)List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

(1)ArrayList

      ArrayList是一個(gè)動(dòng)態(tài)數(shù)組,也是我們最常用的集合,是List類的典型實(shí)現(xiàn)。它允許任何符合規(guī)則的元素插入甚至包括null。每一個(gè)ArrayList都有一個(gè)初始容量(10),該容量代表了數(shù)組的大小。隨著容器中的元素不斷增加,容器的大小也會(huì)隨著增加。在每次向容器中增加元素的同時(shí)都會(huì)進(jìn)行容量檢查,當(dāng)快溢出時(shí),就會(huì)進(jìn)行擴(kuò)容操作。所以如果我們明確所插入元素的多少,最好指定一個(gè)初始容量值,避免過(guò)多的進(jìn)行擴(kuò)容操作而浪費(fèi)時(shí)間、效率。

      ArrayList擅長(zhǎng)于隨機(jī)訪問(wèn)。同時(shí)ArrayList是非同步的。

(2)LinkedList

     LinkedList是List接口的另一個(gè)實(shí)現(xiàn),除了可以根據(jù)索引訪問(wèn)集合元素外,LinkedList還實(shí)現(xiàn)了Deque接口,可以當(dāng)作雙端隊(duì)列來(lái)使用,也就是說(shuō),既可以當(dāng)作“?!笔褂?,又可以當(dāng)作隊(duì)列使用。

  LinkedList的實(shí)現(xiàn)機(jī)制與ArrayList的實(shí)現(xiàn)機(jī)制完全不同,ArrayLiat內(nèi)部以數(shù)組的形式保存集合的元素,所以隨機(jī)訪問(wèn)集合元素有較好的性能;LinkedList內(nèi)部以鏈表的形式保存集合中的元素,所以隨機(jī)訪問(wèn)集合中的元素性能較差,但在插入刪除元素時(shí)有較好的性能。

(3)Vector

      與ArrayList相似,但是Vector是同步的。所以說(shuō)Vector是線程安全的動(dòng)態(tài)數(shù)組。它的操作與ArrayList幾乎一樣。

(4)Stack

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

(5)Iterator接口和ListIterator接口

  Iterator是一個(gè)接口,它是集合的迭代器。集合可以通過(guò)Iterator去遍歷集合中的元素。Iterator提供的API接口如下:

  •  boolean hasNext():判斷集合里是否存在下一個(gè)元素。如果有,hasNext()方法返回 true。
  •  Object next():返回集合里下一個(gè)元素。
  •  void remove():刪除集合里上一次next方法返回的元素。

  ListIterator接口繼承Iterator接口,提供了專門操作List的方法。ListIterator接口在Iterator接口的基礎(chǔ)上增加了以下幾個(gè)方法:

  •  boolean hasPrevious():判斷集合里是否存在上一個(gè)元素。如果有,該方法返回 true。
  •  Object previous():返回集合里上一個(gè)元素。
  •  void add(Object o):在指定位置插入一個(gè)元素。

  以上兩個(gè)接口相比較,不難發(fā)現(xiàn),ListIterator增加了向前迭代的功能(Iterator只能向后迭代),ListIterator還可以通過(guò)add()方法向List集合中添加元素(Iterator只能刪除元素)。

4. Map集合

  Map接口采用鍵值對(duì)Map<K,V>的存儲(chǔ)方式,保存具有映射關(guān)系的數(shù)據(jù),因此,Map集合里保存兩組值,一組值用于保存Map里的key,另外一組值用于保存Map里的value,key和value可以是任意引用類型的數(shù)據(jù)。key值不允許重復(fù),可以為null。如果添加key-value對(duì)時(shí)Map中已經(jīng)有重復(fù)的key,則新添加的value會(huì)覆蓋該key原來(lái)對(duì)應(yīng)的value。常用實(shí)現(xiàn)類有HashMap、LinkedHashMap、TreeMap等。

  Map常見方法(來(lái)源于API)如下:

(1)HashMap與Hashtable

  HashMap與Hashtable是Map接口的兩個(gè)典型實(shí)現(xiàn),它們之間的關(guān)系完全類似于ArrayList與Vertor。HashTable是一個(gè)古老的Map實(shí)現(xiàn)類,它提供的方法比較繁瑣,目前基本不用了,HashMap與Hashtable主要存在以下兩個(gè)典型區(qū)別:

  • HashMap是線程不安全,HashTable是線程安全的。
  • HashMap可以使用null值最為key或value;Hashtable不允許使用null值作為key和value,如果把null放進(jìn)HashTable中,將會(huì)發(fā)生空指針異常。

  為了成功的在HashMap和Hashtable中存儲(chǔ)和獲取對(duì)象,用作key的對(duì)象必須實(shí)現(xiàn)hashCode()方法和equals()方法。

  HashMap工作原理如下:

  HashMap基于hashing原理,通過(guò)put()和get()方法存儲(chǔ)和獲取對(duì)象。當(dāng)我們將鍵值對(duì)傳遞給put()方法時(shí),它調(diào)用建對(duì)象的hashCode()方法來(lái)計(jì)算hashCode值,然后找到bucket位置來(lái)儲(chǔ)存值對(duì)象。當(dāng)獲取對(duì)象時(shí),通過(guò)建對(duì)象的equals()方法找到正確的鍵值對(duì),然后返回對(duì)象。HashMap使用鏈表來(lái)解決碰撞問(wèn)題,當(dāng)發(fā)生碰撞了,對(duì)象將會(huì)存儲(chǔ)在鏈表的下一個(gè)節(jié)點(diǎn)中。

(2)LinkedHashMap實(shí)現(xiàn)類

  LinkedHashMap使用雙向鏈表來(lái)維護(hù)key-value對(duì)的次序(其實(shí)只需要考慮key的次序即可),該鏈表負(fù)責(zé)維護(hù)Map的迭代順序,與插入順序一致,因此性能比HashMap低,但在迭代訪問(wèn)Map里的全部元素時(shí)有較好的性能。

(3)Properties

  Properties類時(shí)Hashtable類的子類,它相當(dāng)于一個(gè)key、value都是String類型的Map,主要用于讀取配置文件。

(4)TreeMap實(shí)現(xiàn)類

  TreeMap是SortedMap的實(shí)現(xiàn)類,是一個(gè)紅黑樹的數(shù)據(jù)結(jié)構(gòu),每個(gè)key-value對(duì)作為紅黑樹的一個(gè)節(jié)點(diǎn)。TreeMap存儲(chǔ)key-value對(duì)時(shí),需要根據(jù)key對(duì)節(jié)點(diǎn)進(jìn)行排序。TreeMap也有兩種排序方式:

  • 自然排序:TreeMap的所有key必須實(shí)現(xiàn)Comparable接口,而且所有的key應(yīng)該是同一個(gè)類的對(duì)象,否則會(huì)拋出ClassCastException。
  • 定制排序:創(chuàng)建TreeMap時(shí),傳入一個(gè)Comparator對(duì)象,該對(duì)象負(fù)責(zé)對(duì)TreeMap中的所有key進(jìn)行排序。

(5)各Map實(shí)現(xiàn)類的性能分析

  • HashMap通常比Hashtable(古老的線程安全的集合)要快
  • TreeMap通常比HashMap、Hashtable要慢,因?yàn)門reeMap底層采用紅黑樹來(lái)管理key-value。
  • LinkedHashMap比HashMap慢一點(diǎn),因?yàn)樗枰S護(hù)鏈表來(lái)爆出key-value的插入順序。

以上就是JAVA集合框架專題的詳細(xì)內(nèi)容,更多關(guān)于JAVA集合框架的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論