Swift中的集合類型,Swift集合類型

來源:互聯網
上載者:User

Swift中的集合類型,Swift集合類型

一.引子:

        在2014年10月TIOBE程式設計語言熱門排行榜中,Swift位居第18位,從2014WWDC發布會首次公布至今不到半年時間,swift一直受到編程人員的追捧,其熱衷程度並不亞於當紅巨星Taylor Swift。相信在不遠的將來,swift能夠平穩發展,並逐步取代Objective-C。


二.swift的集合類型

    下面迴歸主題。作為一名iOS開發人員,我們已經非常熟悉諸如NSArray,NSDictionary,NSSet等常見集合類型,以及它們的可變同類NSMutableArray,NSMutableDictionary,NSMutableSet。而swift則為我們提供了原生的Array和Dictionary集合類型,遺憾的是,目前還沒有提供Set這樣的集合類型(預計將來可能會添加進去)。與Objective-C不同的是,swift不存在對應的mutable類型,原因是一個集合類型是否可變是通過修飾符var和let決定的,因此,如果一個集合類型的變數是let修飾的,則這個集合類型是不可變的。如果一個集合類型的變數是var修飾的,則這個集合類型是可變的。例如:

var mutableArray = Array<Int>()mutableArray.append(1)let immutableArray = Array<String>()immutableArray.append("item")    // 編譯時間錯誤

如果不知道修飾符let和var的區別,可以這樣簡單理解,let修飾的變數是常量,一旦賦值後就不能再改變。而var修飾的變數的值可以動態改變。


三.範型集合

        Objective-C的集合類型對集合裡的元素只有一個要求,那就是它必須是一個OC對象(很多時候我們想要往裡面添加基礎資料型別 (Elementary Data Type)時,都要用NSNumber封裝一下才能放到集合裡去)。而swift則不同,swift宣稱自己是型別安全的,因為swift的特性裡包含現代語言裡都會有的範型(generic)。因此我們在調用集合類型的初始化方法時,都要註明這個集合類型的元素資料類型。比如:

var intArray = Array<Int>()intArray.append(2014)intArray.append("2014")    // 編譯時間錯誤var creditDictionary = Dictionary<String,Int>()creditDictionary.updateValue(88888, forKey: "Benson")


在上面的例子中,聲明了一個整形數組和一個KeyType為String,ValueType為Int的字典。整形數組裡只能存放整形元素,如果放入字串元素,編譯器就會報錯(值得注意的是,如果放入浮點類型或者布爾類型,編譯器會自動將其轉換為整形,比如3.14轉換成3,true轉換為1)。有了範型,就可以確保型別安全,而不用再進行類型判斷和強制類型轉換等麻煩操作。

(數組的元素類型沒有任何限制,但是字典對KeyType設定了類型限制(Type Constraints),它規定KeyType必須實現Hashable協議,該協議規定遵循類必須提供gettable的hashValue屬性。值得慶幸的是,String,Int,Double,Bool等常用類型都實現了該協議,一般情況下夠用了。)

四.簡寫形式

        對於集合類型的初始化,大多數情況下都不採用上面例子中的寫法,而是採用更加簡潔的形式。

var shorthandArray = [Int]()    // var intArray = Array<Int>()var shorthandDictionary = [String:Int]()    // var creditDictionary = Dictionary<String,Int>()

如上所示,對於數群組類型來說,只需在中括弧中聲明數組的類型,接著再跟一對小括弧即可(小括弧裡也可帶有初始化的參數,比如[Int](count:3,repeatedValue:0) ),對於字典類型來說,只需再中括弧中聲明key和value的類型,並以冒號分隔即可,接著再跟一對小括弧,同理,小括弧裡也可帶有相應初始化方法的參數。另外一種情況是,如果已知某個變數為集合類型,那麼再次賦值時可以採用更簡單的形式:

shorthandArray = [] // empty arrayshorthandDictionary = [:]   // empty dictionary

由於類型已知,因此無需在中括弧中聲明相應的類型。


五.集合類型的遍曆

    集合類型最常用的操作莫過於遍曆集合。下面分別針對數組和字典進行遍曆:

var carArray = [String]()carArray.append("Mercedes-Benz")carArray.append("Toyota")carArray.append("Porsche")for car in carArray {    println(car)}

上面的例子中採用for in 迴圈,迴圈列印數組中每個元素。(println是swift內建全域函數,類似於java的System.out.println()方法。另外可以看到for迴圈中無需用小括弧包圍)

輸出結果:

(這浮水印。。)


如果在迴圈過程中需要得到索引值,可以使用swift標準庫中的全域函數enumerate:

for (index,value) in enumerate(carArray) {    println("index\(index):\(value)")}

列印結果:

index0:Mercedes-Benzindex1:Toyotaindex2:Porsche

接下來是遍曆字典:

var animalLegs = [String:Int]()animalLegs.updateValue(4, forKey: "deer")animalLegs.updateValue(8, forKey: "crab")animalLegs.updateValue(2, forKey: "kangaroo")for (animal,legs) in animalLegs {    println("\(animal) has \(legs)leg(s)")}

和遍曆數組類似,只不過遍曆的每一項是一個元組(tuple),該元組包含兩個元素,一個是key,一個是value。


六.使用下標(subscript)

    數組Array和字典Dictionary可以使用下標的形式進行添加,刪除和替換等操作,比如:

var carArray = [String]()carArray.append("Mercedes-Benz")carArray.append("Toyota")carArray.append("Porsche")carArray[0] = "BMW"  // 平治被替換成寶馬了 [ replace 操作]var animalLegs = [String:Int]()animalLegs.updateValue(4, forKey: "deer")animalLegs.updateValue(8, forKey: "crab")animalLegs.updateValue(2, forKey: "kangaroo")animalLegs["sheep"] = 4     // 添加一個元素animalLegs["deer"] = nil    // 刪除一個元素animalLegs["crab"] = 6      // 替換元素的值if let legs = animalLegs["kangaroo"] {    println("kangaroo has \(legs)legs")} else {    println("not defined")}

針對數組的操作,下標好像只能進行替換,不能添加元素,也不能刪除元素(如果將某個元素設定為nil,需將數組的元素類型設定為optional)。

針對字典的操作則比較齊全,可以進行CRUD。需要特別注意的是,通過下標擷取字典某個key的值的時候,返回的類型是ValueType?(即optional的值類型),可以採用optional binding或者if和!搭配使用提取該值,因為字典中可能不存在該值,從而可能為nil。


七.集合類型的簡便初始化

    可能是說漏了,但也是最重要的一點,就是如何利用數組和字典的字面量(literal)對變數進行賦值。

var countryArray = ["China","Japan","Russia","India","Canada"]var festivalDic = ["National's Day":"10-01","Christmas Day":"12-25","New Year":"01-01"]

數組的字面量一般形式是[value,value,value...],字典的一般形式是[key:value,key:value,key:value,...]。數組和字典的資料類型是通過類型推導(type inferrence)得出來的,對於數組來說,由於數組裡的元素都是String,因此countryArray的資料類型是[String],同理,festivalDic的資料類型是[String:String]。


最後需要強調一點的是,Array和Dictionary跟OC的NSArray和NSDictionary不同,Array和Dictionary是值類型(value type),不是參考型別,因此,Array和Dictionary傳值一般都是copy,其原始值不會受到影響:(更具體一點,Array和Dictionary都是struct類型,String也不例外。)

var original = [1,2,3]var steal = originalsteal.append(4)original.count // 3steal.count    // 4



JAVA的集合類型有什

Java API中所用的集合類,都是實現了Collection介面,他的一個類繼承結構如下:

Collection<--List<--Vector

Collection<--List<--ArrayList

Collection<--List<--LinkedList

Collection<--Set<--HashSet

Collection<--Set<--HashSet<--LinkedHashSet

Collection<--Set<--SortedSet<--TreeSet

Vector : 基於Array的List,其實就是封裝了Array所不具備的一些功能方便我們使用,它不可能走入Array的限制。效能也就不可能

超越Array。所以,在可能的情況下,我們要多運用Array。另外很重要的一點就是Vector“sychronized”的,這個也是Vector和

ArrayList的唯一的區別。

ArrayList:同Vector一樣是一個基於Array上的鏈表,但是不同的是ArrayList不是同步的。所以在效能上要比Vector優越一些,但

是當運行到多線程環境中時,可需要自己在管理線程的同步問題。

LinkedList:LinkedList不同於前面兩種List,它不是基於Array的,所以不受Array效能的限制。它每一個節點(Node)都包含兩方

面的內容:1.節點本身的資料(data);2.下一個節點的資訊(nextNode)。所以當對LinkedList做添加,刪除動作的時候就不用像

基於Array的List一樣,必須進行大量的資料移動。只要更改nextNode的相關資訊就可以實現了。這就是LinkedList的優勢。

List總結:

1. 所有的List中只能容納單個不同類型的對象組成的表,而不是Key-Value索引值對。例如:[ tom,1,c ];

2. 所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ];

3. 所有的List中可以有null元素,例如[ tom,null,1 ];

4. 基於Array的List(Vector,ArrayList)適合查詢,而LinkedList(鏈表)適合添加,刪除操作。

HashSet:雖然Set同List都實現了Collection介面,但是他們的實現方式卻大不一樣。List基本上都是以Array為基礎。但是Set則是

在HashMap的基礎上來實現的,這個就是Set和List的根本區別。HashSet的儲存方式是把HashMap中的Key作為Set的對應儲存項。
 
c#中的集合屬於參考型別還是實值型別

參考型別
 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.