Kotlin容器知識點期末複習

轉載來自: https://blog.csdn.net/aqi00/article/details/82699463

期中考試拿來查的知識點,期末會用到

 

Kotlin號稱全面兼容Java,於是乎Java的容器類仍可在Kotlin中正常使用,包括大家熟悉的隊列ArrayList、映射HashMap等等。不過Kotlin作爲一門全新的語言,肯定還是要有自己的容器類,不然哪天Java跟Kotlin劃清界限,那麻煩就大了。與Java類似,Kotlin也擁有三類基本的容器,分別是集合Set、隊列List、映射Map,然後每類容器又分作只讀與可變兩種類型,這是爲了判斷該容器能否進行增刪改等變更操作。Kotlin對修改操作很慎重,比如變量用val前綴表示不可修改,用var前綴表示允許修改;類默認是不允許繼承的,只有添加open前綴才允許該類被繼承;至於容器默認爲只讀容器,如果需要進行修改則需加上Mutable形成新的容器,比如MutableSet表示可變集合,MutableList表示可變隊列,MutableMap表示可變映射。

既然Set/List/Map都屬於容器,那麼必定擁有相同的基本容器方法,具體說明如下:
isEmpty : 判斷該容器是否爲空。
isNotEmpty : 判斷該容器是否非空。
clear : 清空該容器。
contains : 判斷該容器是否包含指定元素。
iterator : 獲取該容器的迭代器。
count : 獲取該容器包含的元素個數,也可通過size屬性獲得元素數量。
初始化賦值 : Kotlin允許在聲明容器變量之時進行初始賦值,這點很方便比Java先進,當然不同容器的初始化方法有所區別,具體的對應關係見下表:
只讀集合Set    setOf
可變集合    mutableSetOf
只讀隊列List    listOf
可變隊列MutableList    mutableListOf
只讀映射Map    mapOf
可變映射MutableMap    mutableMapOf
以上是Kotlin容器的基本方法,更具體的增刪改查等用法則有所不同,下面分別介紹這三類六種容器的詳細用法。
只讀集合Set/可變集合MutableSet

集合是一種簡單的容器,它具有以下特性:
1、容器內部的元素不按順序排列,因此無法按照下標進行訪問;
2、容器內部的元素存在唯一性,通過哈希值校驗是否存在相同的元素,如果存在則覆蓋之;
因爲Set是隻讀集合,初始化賦值後便不可更改,所以元素變更的方法只適用於可變集合MutableSet,但MutableSet的變更操作尚有以下限制:
1、MutableSet的add方法僅僅往集合中添加元素,由於集合是無序的,因此不知道添加的具體位置;
2、MutableSet沒有修改元素值的方法,一個元素一旦被添加,就不可被修改;
3、MutableSet的remove方法用於刪除指定對象,但無法刪除某個位置的元素,這是因爲集合內的元素不是按順序排列的;

對於集合的遍歷操作,Kotlin提供了好幾種方式,有熟悉的for循環,有迭代器循環,還有新面孔forEach循環,三種循環遍歷的用法說明如下:
1、for-in循環

與Java類似,通過for語句加上in條件,即可輕輕鬆鬆依次取出集合中的所有元素。下面是運用了for-in循環的代碼例子:

        btn_set_for.setOnClickListener {
            var desc = ""
            //使用for-in語句循環取出集合中的每條記錄
            for (item in goodsMutSet) {
                desc = "${desc}名稱:${item.name},價格:${item.price}\n"
            }
            tv_set_result.text = "手機暢銷榜包含以下${goodsMutSet.size}款手機:\n$desc"
        }

2、迭代器循環

迭代器與指針的概念有點接近,它自身並非具體的元素,而是指向元素的存放地址,所以迭代器循環其實是遍歷所有元素的地址。迭代器通過hasNext方法判斷是否還存在下一個節點,如果不存在下一節點則表示已經遍歷完畢;它通過next方法獲得下一個節點的元素,同時迭代器自身改爲指向該元素的地址。下面是運用了迭代器循環的代碼例子:

       

btn_set_iterator.setOnClickListener {
            var desc = ""
            val iterator = goodsMutSet.iterator()
            //如果迭代器還存在下一個節點,則繼續取出下一個節點的記錄
            while (iterator.hasNext()) {
                val item = iterator.next()
                desc = "${desc}名稱:${item.name},價格:${item.price}\n"
            }
            tv_set_result.text = "手機暢銷榜包含以下${goodsMutSet.size}款手機:\n$desc"
        }

3、forEach循環

不管是for-in循環還是迭代器循環,其實都脫胎於Java已有的容器遍歷操作,代碼書寫上不夠精煉。爲了將代碼精簡做到極致,Kotlin給容器創造了forEach方法,明確指定該方法就是要依次遍歷容器。forEach方法在編碼時採用匿名函數的形式,內部使用it代表每個元素的對象,下面是運用了forEach循環的代碼例子:

      

  btn_set_foreach.setOnClickListener {
            var desc = ""
            //forEach內部使用it指代每條記錄
            goodsMutSet.forEach { desc = "${desc}名稱:${it.name},價格:${it.price}\n" }
            tv_set_result.text = "手機暢銷榜包含以下${goodsMutSet.size}款手機:\n$desc"
        }

結合以上有關Set的用法說明,我們發現集合在實戰中存在諸多不足,主要包括以下幾點:
1、集合不允許修改內部元素的值;
2、集合無法刪除指定位置的元素;
3、不能通過下標獲取指定位置的元素;
鑑於集合的以上缺點難以克服,故而實際開發基本用不到集合,大多數場合用的是它的兩個兄弟——隊列和映射。
只讀隊列List/可變隊列MutableList

隊列是一種元素之間按照順序排列的容器,它與集合的最大區別,便是多了個次序管理。不要小看這個有序性,正因爲隊列建立了秩序規則,所以它比集合多提供瞭如下功能(注意凡是涉及到增刪改的,都必須由MutableList來完成):
1、隊列的get方法能夠獲取指定位置的元素,也可直接通過下標獲得該位置的元素。
2、MutableList的add方法每次都是把元素添加到隊列末尾,也可指定添加的位置;
3、MutableList的set方法允許替換或者修改指定位置的元素;
4、MutableList的removeAt方法允許刪除指定位置的元素;
5、MutableList提供了sort系列方法用於給隊列中的元素重新排序,其中sortBy方法表示按照升序排列,sortByDescending方法表示按照降序排列;下面是個給隊列排序的代碼例子:

        var sortAsc = true
        btn_sort_by.setOnClickListener {
            if (sortAsc) {
                //sortBy表示升序排列,後面跟的是排序條件
                goodsMutList.sortBy { it.price }
            } else {
                //sortByDescending表示降序排列,後面跟的是排序條件
                goodsMutList.sortByDescending { it.price }
            }
            var desc = ""
            for (item in goodsMutList) {
                desc = "${desc}名稱:${item.name},價格:${item.price}\n"
            }
            tv_list_result.text = "手機暢銷榜已按照${if (sortAsc) "升序" else "降序"}重新排列:\n$desc"
            sortAsc = !sortAsc
        }

5、隊列除了擁有跟集合一樣的三種遍歷方式(for-in循環、迭代器循環、forEach循環),另外多了一種按元素下標循環遍歷的方式,具體下標遍歷的代碼例子如下所示:

     

   btn_for_index.setOnClickListener {
            var desc = ""
            //indices是隊列的下標數組。如果隊列大小爲10,則下標數組的取值爲0到9
            for (i in goodsMutList.indices) {
                val item = goodsMutList[i]
                desc = "${desc}名稱:${item.name},價格:${item.price}\n"
            }
            tv_list_result.text = "手機暢銷榜包含以下${goodsMutList.size}款手機:\n$desc"
        }

只讀映射Map/可變映射MutableMap

映射內部保存的是一組鍵值對(Key-Value),也就是說,每個元素都由兩部分構成,第一部分是元素的鍵,相當於元素的名字;第二部分是元素的值,存放着元素的詳細信息。元素的鍵與值是一一對應的關係,相同的鍵名指向的值對象是唯一的,所以映射中每個元素的鍵名各不相同,這個特性使得映射的變更操作與隊列存在以下不同之處(注意增刪操作必須由MutableMap來完成):
1、映射的containsKey方法判斷是否存在指定鍵名的元素,containsValue方法判斷是否存在指定值對象的元素;
2、MutableMap的put方法不單單是添加元素,而是智能的數據存儲;每次調用put方法,映射會先根據鍵名尋找同名元素,如果找不到就添加新元素,如果找得到就用新元素替換舊元素;
3、MutableMap的remove方法,是通過鍵名來刪除元素的;
4、調用mapOf和mutableMapOf方法初始化映射之時,有兩種方式可以表達單個鍵值對元素。其一是採取“鍵名 to 值對象”的形式,其二是採取Pair配對方式形如“Pair(鍵名, 值對象)”,下面是這兩種初始化方式的代碼例子:

    //to方式初始化映射
    var goodsMap = mapOf("蘋果" to goodsA, "華爲" to goodsB, "小米" to goodsC, "歐珀" to goodsD, "步步高" to goodsE, "魅族" to goodsF)
    //Pair方式初始化映射
    var goodsMutMap = mutableMapOf(Pair("蘋果", goodsA), Pair("華爲", goodsB), Pair("小米", goodsC), Pair("歐珀", goodsD), Pair("步步高", goodsE), Pair("魅族", goodsF))

映射的遍歷與集合類似,也有for-in循環、迭代器循環、forEach循環三種遍歷手段。但是由於映射的元素是個鍵值對,因此它的循環遍歷方式與集合稍有不同,詳述如下:
1、for-in循環

for-in語句取出來的是映射的鍵值對元素,若要獲取該元素的鍵名,還需訪問元素的key屬性;若要獲取該元素的值對象,還需訪問元素的value屬性。下面是在映射中運用for-in循環的代碼例子:

       

 btn_map_for.setOnClickListener {
            var desc = ""
            //使用for-in語句循環取出映射中的每條記錄
            for (item in goodsMutMap) {
                //item.key表示該配對的鍵,即廠家名稱;item.value表示該配對的值,即手機信息
                desc = "${desc}廠家:${item.key},名稱:${item.value.name},價格:${item.value.price}\n"
            }
            tv_map_result.text = "手機暢銷榜包含以下${goodsMutMap.size}款手機:\n$desc"
        }

2、迭代器循環

映射的迭代器通過next函數得到下一個元素,也需訪問該元素的key屬性獲取鍵名,訪問該元素的value屬性獲取值對象。下面是在映射中運用迭代器循環的代碼例子:

        btn_map_iterator.setOnClickListener {
            var desc = ""
            val iterator = goodsMutMap.entries.iterator()
            //如果迭代器還存在下一個節點,則繼續取出下一個節點的記錄
            while (iterator.hasNext()) {
                val item = iterator.next()
                desc = "${desc}廠家:${item.key},名稱:${item.value.name},價格:${item.value.price}\n"
            }
            tv_map_result.text = "手機暢銷榜包含以下${goodsMutMap.size}款手機:\n$desc"
        }

3、forEach循環

映射的forEach方法內部依舊採用匿名函數的形式,同時把元素的key和value作爲匿名函數的輸入參數。不過映射的forEach函數需要API24及以上版本支持,開發時注意修改編譯配置。下面是在映射中運用forEach循環的代碼例子:

        btn_map_foreach.setOnClickListener {
            //var desc = ""
            ////映射的forEach函數需要API24及以上版本支持
            ////forEach內部使用key指代每條記錄的鍵,使用value指代每條記錄的值
            //goodsMap.forEach { key, value -> desc = "${desc}廠家:${key},名稱:${value.name},價格:${value.price}\n" }
            //tv_map_result.text = "手機暢銷榜包含以下${goodsMutMap.size}款手機:\n$desc"
            tv_map_result.text = "Map的forEach函數需要API24及以上版本支持"
        }

 

點此查看Kotlin入門教程的完整目錄:

https://blog.csdn.net/aqi00/article/details/75283548

本系列教程的所有源碼均可到我的github主頁下載,頁面地址是

https://github.com/aqi00/kotlin
 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章