Kotlin基礎(三)

Kotlin基礎(三)

3.集合類

3.1 不可變List

  • 使用 listOf 函數來構建一個不可變的List(read-only,只讀的List)。

    //空List,變量的類型不能省略
    val list:List<Int> = listOf()
    //只有1個元素的List
    val list = listOf(1)
    //有多個元素的List
    val list = listOf(0,1, 2, 3, 4, 5, 6,7,8,9)
    //可以使用 arrayListOf 函數創建一個Java中的ArrayList對象實例
    val list = arrayListOf(0,1,2,3)
    

3.2 可變集合MutableList

  • MutableList中,除了繼承List中的那些函數外,另外新增了add/addAll、remove/removeAll/removeAt、set、clear、retainAll等更新修改的操作函數。

  • 對於一個不可變的List,可以直接調用轉換函數 toMutableList 轉換成可變的List。

    val list = mutableListOf(1, 2, 3)
    val mlist = list.toMutableList()
    mlist.add(5)
    

3.3 遍歷List元素

  • 使用Iterator迭代器:

    val list = listOf(0,1, 2, 3, 4, 5, 6,7,8,9)
    val iterator = list.iterator()
    while(iterator.hasNext()){
        println(iterator.next())
    }
    
  • 使用 forEach

    val list = listOf(0,1, 2, 3, 4, 5, 6,7,8,9)
    list.forEach{
        println(it)
    }
    //簡寫
    list.forEach(::println)
    
  • :: 是函數引用符。

3.4 List元素操作函數

  • add/addAll、remove/removeAll/removeAt、set、clear不介紹。

  • 取兩個集合交集:retainAll

    val mlist1 = mutableListOf(1,2,3,4,5,6)
    val mlist2 = mutableListOf(3,4,5,6,7,8,9)
    mlist1.retainAll(mlist2)	//true
    mlist1	//[3, 4, 5, 6]
    
  • 判斷集合中是否有指定元素,有就返回true,否則返回false:contains(element: T): Boolean

  • 查找下標對應的元素:

    • elementAt(index: Int): T 越界會拋IndexOutOfBoundsException。
    • elementAtOrElse(index: Int, defaultValue: (Int) -> T): T 越界會根據方法返回默認值。
    • elementAtOrNull(index: Int): T? 越界返回null
  • 返回集合第1個元素:

    • first() 如果是空集,拋出異常NoSuchElementException。

    • firstOrNull(): T? 空集返回null

    • first(predicate: (T) -> Boolean): T 返回符合條件的第一個元素,沒有則拋異常NoSuchElementException 。

      val list = listOf(1,2,3)
      list.first({it%2==0})  //2
      
    • firstOrNull(predicate: (T) -> Boolean): T? 返回符合條件的第一個元素,沒有就返回null。

  • 返回指定下標的元素,沒有就返回-1:indexOf(element: T): Int

  • 返回第一個符合條件的元素下標,沒有就返回-1 :indexOfFirst(predicate: (T) -> Boolean): Int

  • 返回最後一個符合條件的元素下標,沒有就返回-1 :indexOfLast(predicate: (T) -> Boolean): Int

  • 返回集合最後1個元素:

    • last()
    • last(predicate: (T) -> Boolean): T
    • lastIndexOf(element: T): Int
  • 集合如果只有1個元素,則返回該元素,否則,拋異常:single(): T

  • 返回符合條件的單個元素,如有沒有符合的拋異常NoSuchElementException,或超過一個的拋異常
    IllegalArgumentException:single(predicate: (T) -> Boolean): T

3.5 List集合類的函數算子(operator)

  • any(): 判斷集合至少有一個元素,有則返回 true ,否則返回 false 。

  • any(predicate: (T) -> Boolean) :判斷集合中是否有滿足條件的元素。

  • all(predicate: (T) -> Boolean): 判斷集合中的元素是否都滿足條件。

  • none():判斷集合無元素,沒有任何元素返回 true ,否則返回 false 。

  • **count():**計算集合中元素的個數。

  • count(predicate: (T) -> Boolean) :計算集合中滿足條件的元素的個數。

  • reduce:從第一項到最後一項進行累計運算。

    /**
     * 首先把第一個元素賦值給累加子accumulator,然後逐次向後取元素累加,新值繼續賦值給 	
     * 累加子accumulator = operation(accumulator, iterator.next()),以此類推。
     * 最後返回累加子的值。
    */
    val list = listOf(1,2,3,4,5,6,7,8,9)
    list.reduce({sum, next->sum+next}) //45
    list.reduce({sum, next->sum*next}) //362880
    
  • reduceRight:從最後一項到第一項進行累計運算。

    /**
     * accumulator = operation(iterator.previous(), accumulator)
     * 可以看出,從右邊累計運算的累加子是放在後面的。
    */
    val list = listOf("a","b","c")
    list.reduceRight({total, s -> s+total})  //cba
    
  • fold(initial: R, operation: (acc: R, T) -> R):R:帶初始值的reduce。

    val list=listOf(1,2,3,4)
    list.fold(100,{total, next -> next + total})	//110
    /**
     * foldRight 和 reduceRight 類似,有初始值。
    **/
    val list = listOf("a","b","c")
    list.foldRight("xyz",{s, pre -> pre + s})	//xyzcba
    
  • forEach(action: (T) -> Unit): Unit:循環遍歷元素,元素是it。

    val list = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    list.forEach { value -> if (value > 7) println(value) } //8 9
    
  • forEachIndexed :帶index(下標) 的元素遍歷。

    val list = listOf(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
    list.forEachIndexed { index, value -> if (value > 8) println("value of index $index is $value, greater than 8") }  
    // value of index 9 is 9, greater than 8
    
  • maxmin :查詢最大、最小的元素,空集則返回null。

  • maxBy(selector: (T) -> R): T?minBy(selector: (T) -> R): T? :獲取函數映射結果的最大值、最小值對應的那個元素的值,如果沒有則返回null。

    val list = listOf(100,-500,300,200)
    list.maxBy({it})	//300
    list.maxBy({it*(1-it)})	//100
    list.maxBy({it*it})	//-500
    
  • sumBy(selector: (T) -> Int): Int: 獲取函數映射值的總和。

    val list = listOf(1,2,3,4)
    list.sumBy({it})	//10
    list.sumBy({it*it})	//30
    

3.6 過濾操作函數算子

  • take(n: Int): List :挑出該集合前n個元素的子集合。

    val list = listOf("a","b","c")
    list.take(2)	//[a, b]
    list.take(10)	//[a, b, c]
    list.take(0)	//[]
    
  • takeWhile(predicate: (T) -> Boolean): List :挑出滿足條件的元素的子集合。

    val list = listOf(1,2,4,6,8,9)
    list.takeWhile({it%2==0})	//[]
    list.takeWhile({it%2==1})	//[1]
    val list = listOf(2,4,6,8,9,11,12,16)
    list.takeWhile({it%2==0})	//[2, 4, 6, 8]
    
  • takeLast :挑出後n個元素的子集合。

  • takeLastWhile(predicate: (T) -> Boolean) :從最後開始挑出滿足條件元素的子集合。

  • drop(n: Int) :去除前n個元素返回剩下的元素的子集合。

    val list = listOf(2,4,6,8,9,11,12,16)
    list.drop(5)	//[11, 12, 16]
    list.drop(100)	//[]
    
  • dropWhile(predicate: (T) -> Boolean) :去除滿足條件的元素返回剩下的元素的子集合。

    val list = listOf(2,4,6,8,9,11,12,16)
    list.dropWhile({it%2==0})	//[9, 11, 12, 16]
    
  • dropLast(n: Int):從最後去除n個元素。

  • dropLastWhile(predicate: (T) -> Boolean) :從最後滿足條件的元素。

  • slice(indices: IntRange):取開始下標至結束下標元素子集合。

    val list = listOf(2,4,6,8,9,11,12,16)
    list.slice(1..3)	//[4, 6, 8]
    
  • slice(indices: Iterable<Int>) :返回指定下標的元素子集合。

    val list = listOf(2,4,6,8,9,11,12,16)
    list.slice(listOf(2,4,6))	//[6, 9, 12]
    
  • filterTo(destination: C, predicate: (T) -> Boolean) :過濾出滿足條件的元素並賦值給destination。

    val list = listOf(1,2,3,4,5,6,7)
    val dest = mutableListOf<Int>()
    list.filterTo(dest,{it>3})	//[4, 5, 6, 7]
    dest	//[4, 5, 6, 7]
    
  • filter(predicate: (T) -> Boolean) :過濾出滿足條件的元素組成的子集合。

  • filterNot(predicate: (T) -> Boolean) :過濾所有不滿足條件的元素

  • filterNotNull():過濾掉 null 元素。

3.7 映射操作符

  • map(transform: (T) -> R): List<R>:將集合中的元素通過轉換函數 transform 映射後的結果,存到一個集合中返回。

    val list = listOf(1,2,3,4,5,6,7)
    list.map({it})	//[1, 2, 3, 4, 5, 6, 7]
    list.map({it*it})	//[1, 4, 9, 16, 25, 36, 49]
    
  • mapIndexed(transform: (kotlin.Int, T) -> R):轉換函數 transform 中帶有下標參數。可以同時使用下標和元素的值來進行轉換。

    val list = listOf(1,2,3,4,5,6,7)
    list.mapIndexed({index,it -> index*it})	//[0, 2, 6, 12, 20, 30, 42]
    
  • mapNotNull(transform: (T) -> R?):遍歷集合每個元素,得到通過函數算子transform映射之後的值,剔除掉這些值中的null,返回一個無null元素的集合。

  • flatMap(transform: (T) -> Iterable<R>): List<R>:在原始集合的每個元素上調用 transform 轉換函數,得到的映射結果組成的單個列表。

    val list = listOf("a","b","c")
    list.map({it->listOf(it+1,it+2,it+3)})
    //[[a1, a2, a3], [b1, b2, b3], [c1, c2, c3]]
    // 對比
    list.flatMap({it->listOf(it+1,it+2,it+3)})
    //[a1, a2, a3, b1, b2, b3, c1, c2, c3]
    
    //等價於
    val list = listOf("a","b","c")
    list.map({it->listOf(it+1,it+2,it+3)})
    //[[a1, a2, a3], [b1, b2, b3], [c1, c2, c3]]
    //對比
    list.map({it->listOf(it+1,it+2,it+3)}).flatten()
    //[a1, a2, a3, b1, b2, b3, c1, c2, c3]
    

3.8 分組操作符

  • groupBy(keySelector: (T) -> K): Map<K, List<T>>:將集合中的元素按照條件選擇器 keySelector (是一個函數)分組,並返回Map。

    val words = listOf("a", "abc", "ab", "def", "abcd")
    val lengthGroup = words.groupBy { it.length }
    lengthGroup	//{1=[a], 3=[abc, def], 2=[ab], 4=[abcd]}
    
  • groupBy(keySelector: (T) -> K, valueTransform: (T) -> V):根據條件選擇器keySelector和轉換函數valueTransform分組。

    val programmer = listOf("K&R" to "C", "Bjar" to "C++", "Linus" to "C", "James" to "Java")
    programmer
    //[(K&R, C), (Bjar, C++), (Linus, C), (James, Java)]
    programmer.groupBy({it.second}, {it.first})
    //{C=[K&R, Linus], C++=[Bjar], Java=[James]}
    
    
    //另一個例子
    
    val words = listOf("a", "abc", "ab", "def", "abcd")
    words.groupBy( { it.length })
    //{1=[a], 3=[abc, def], 2=[ab], 4=[abcd]}
    words.groupBy( { it.length },{it.contains("b")})
    //{1=[false], 3=[true, false], 2=[true], 4=[true]}
    
    //另一個例子
    val words = "one two three four five six seven eight nine ten".split(' ')
    words.groupingBy({it.first()}).eachCount()
    //{o=1, t=3, f=2, s=2, e=1, n=1}
    

3.9 排序操作符

  • reversed():倒序排列集合元素。
  • sorted():升序排序。
  • sortedDescending():降序排序。
  • sortedBy()sortedByDescending():可變集合MutableList的排序操作。根據函數映射的結果進行升序排序和降序排序。

3.10 生產操作符

  • zip(other: Iterable<R>): List<Pair<T, R>>:兩個集合按照下標配對,組合成的每個Pair作爲新的List集合中的元素,並返回。如果兩個集合長度不一樣,取短的長度。

    val list1 = listOf(1,2,3)
    val list2 = listOf(4,5,6,7)
    val list3 = listOf("x","y","z")
    list1.zip(list3)
    //[(1, x), (2, y), (3, z)]
    list3.zip(list1)
    //[(x, 1), (y, 2), (z, 3)]
    list2.zip(list3)
    //[(4, x), (5, y), (6, z)] // 取短的長度
    list3.zip(list2)
    //[(x, 4), (y, 5), (z, 6)]
    list1.zip(listOf<Int>())
    //[]
    
  • zip(other) { t1, t2 -> t1 to t2 }:

    val list1 = listOf(1,2,3)
    val list2 = listOf(4,5,6,7)
    val list3 = listOf("x","y","z")
    list1.zip(list3, {t1,t2 -> t2+t1})
    //[x1, y2, z3]
    list1.zip(list2, {t1,t2 -> t1*t2})
    //[4, 10, 18]
    
  • unzip(): Pair<List<T>, List<R>>:作用在元素是Pair的集合類上。依次取各個Pair元素的first, second值,分別放到List、List中,然後返回一個first爲List,second爲List的大的Pair。

    val listPair = listOf(Pair(1,2),Pair(3,4),Pair(5,6))
    listPair
    //[(1, 2), (3, 4), (5, 6)]
    listPair.unzip()
    //([1, 3, 5], [2, 4, 6])
    
  • partition(predicate: (T) -> Boolean): Pair<List<T>, List<T>>:根據判斷條件是否成立,將集合拆分成兩個子集合組成的 Pair。

    val list = listOf(1,2,3,4,5,6,7,8,9)
    list.partition({it>5})
    //([6, 7, 8, 9], [1, 2, 3, 4, 5])
    
  • plus(elements: Iterable): List:合併兩個List。

    val list1 = listOf(1,2,3)
    val list2 = listOf(4,5)
    list1.plus(list2)
    //[1, 2, 3, 4, 5]
    list1+list2 //可以用”+”替代 。
    //[1, 2, 3, 4, 5]
    
  • plusElement(element: T): List<T>:在集合中添加一個元素。


3.11 Set

  • Kotlin中的Set也分爲:不可變Set和支持增加和刪除的可變MutableSet

3.12 創建Set

//空集
val emptySet = emptySet<Int>()
emptySet	//[]
emptySet.size	//0
emptySet.isEmpty()	//true
emptySet.hashCode()	//0

//非空集
val set = setOf(1,1,2,3,3)
val s = setOf<Int>(1)

//list 轉 set  (可去重)
list.toSet()	//[1, 2, 3]

3.13 使用Java中的Set類

val hs = hashSetOf(1,3,2,7)
hs::class
//class java.util.HashSet
val ls = linkedSetOf(1,3,2,7)
ls::class
//class java.util.LinkedHashSet
val ms = mutableSetOf(1,3,2,7)
ms::class
//class java.util.LinkedHashSet
val ss = sortedSetOf(1,3,2,7)
ss::class
//class java.util.TreeSet
  • HashSet : 該類按照哈希算法來存取集合中的對象**,存取速度較快**。
  • TreeSet : 該類實現了SortedSet接口,能夠對集合中的對象進行排序
  • LinkedHashSet:具有HashSet的查詢速度,且內部使用鏈表維護元素的順序,在對Set元素進行頻繁插入、刪除的場景中使用

3.15 Set元素的加減操作

val ms = mutableSetOf(1,3,2,7)
ms+10
//[1, 3, 2, 7, 10]
ms-1
//[3, 2, 7]
ms + listOf(8,9)
//[1, 3, 2, 7, 8, 9]
ms - listOf(8,9)
//[1, 3, 2, 7]
ms - listOf(1,3)
//[2, 7]

3.16 Map

  • Map是一種把鍵對象Key和值對象Value映射的集合。
  • Kotlin中的Map與List、Set一樣,Map也分爲只讀Map和可變的MutableMap。

3.17 創建Map

//創建一個只讀空Map
val map1 = mapOf<String, Int>()
map1.size	//0
map1.isEmpty()	//true
//方式2
val map2 = emptyMap<String, Int>()
map2.size	//0
map2.isEmpty()	//true
//空Map都是相等的
map2==map1
true

//使用二元組Pair創建一個只讀Map
val map = mapOf(1 to "x", 2 to "y", 3 to "z")
map	//{1=x, 2=y, 3=z}
map.get(1)	//x
map.entries	//[1=x, 2=y, 3=z]


//創建一個空的可變的Map
val map = mutableMapOf<Int, Any?>()
map.isEmpty()	//true
map[1] = "x"
map[2] = 1
map		//{1=x, 2=1}

//創建一個非空的可變的Map
val map = mutableMapOf(1 to "x", 2 to "y", 3 to "z")
map		//{1=x, 2=y, 3=z}
map[1]="a"
map		//{1=a, 2=y, 3=z}
  • 如果Map中有重複的key鍵,後面的會直接覆蓋掉前面的

3.18 使用Java中的Set類

  • 創建HashMap對象。Kotlin直接使用的是Java的HashMap。
val map: HashMap<Int, String> = hashMapOf(1 to "x", 2 to "y", 3 to "z")
map		//{1=x, 2=y, 3=z}
  • 創建空對象LinkedHashMap。直接使用的是Java中的LinkedHashMap。

  • 創建帶二元組Pair元素的LinkedHashMap對象。直接使用的是Java中的LinkedHashMap。

    val map: LinkedHashMap<Int, String> = linkedMapOf()
    map		//{}
    
    val map: LinkedHashMap<Int, String> = linkedMapOf(1 to "x", 2 to "y", 3 to "z")
    map		//{1=x, 2=y, 3=z}
    
  • 創建一個根據Key升序排序好的TreeMap。對應的是使用Java中的SortedMap。

    val map = sortedMapOf(Pair("c", 3), Pair("b", 2), Pair("d", 1))
    map		//{b=2, c=3, d=1}
    

3.19 訪問Map的元素

  • 訪問entries屬性:
val map = mapOf("x" to 1, "y" to 2, "z" to 3)
map		//{x=1, y=2, z=3}
map.entries		//[x=1, y=2, z=3]
map.entries.forEach({println("key="+ it.key + " value=" + it.value)})
//key=x value=1
//key=y value=2
//key=z value=3
  • 訪問keys屬性:

    map.keys	//[x, y, z]
    
  • 訪問values屬性:

    map.values		//[1, 2, 3]
    
  • size屬性:

    map.size		//3
    
  • get(key: K):使用get函數來通過key來獲取value的值,對應的操作符是 []

    map["x"]	//1
    map.get("x")	//1
    //如果這個key不在Map中,就返回null
    map["k"]	//null
    //不想返回null,可以使用getOrDefault函數,設置的一個默認值,默認值的類型要對應
    map.getOrDefault("k",0)		//0
    

3.20 Map操作符函數

  • containsKey(key: K): Boolean:是否包含該key。

  • containsValue(value: V): Boolean:是否包含該value。

  • component1()component2():Map.Entry<K, V> 的操作符函數,分別用來直接訪問key和value。

    val map = mapOf("x" to 1, "y" to 2, "z" to 3)
    map.entries.forEach({println("key="+ it.component1() + " value=" + it.component2())
                        })
    //key=x value=1
    //key=y value=2
    //key=z value=3
    
  • Map.Entry<K, V>.toPair(): Pair<K, V>:把Map的Entry轉換爲Pair。

    map.entries		//[x=1, y=2, z=3]
    map.entries.forEach({println(it.toPair())})
    //(x, 1)
    //(y, 2)
    //(z, 3)
    
  • getOrElse(key: K, defaultValue: () -> V): V:通過key獲取值,當沒有值可以設置默認值。

  • getValue(key: K): V:當Map中不存在這個key,調用get函數,如果不想返回null,直接拋出異常,可調用此方法。

  • getOrPut(key: K, defaultValue: () -> V): V:如果不存在這個key,就添加這個key到Map中,對應的value是defaultValue。

  • iterator(): Iterator<Map.Entry<K, V>>:返回的是 entries.iterator() 。

    val map = mapOf("x" to 1, "y" to 2, "z" to 3 )
    for((k,v) in map){println("key=$k, value=$v")}
    //key=x, value=1
    //key=y, value=2
    //key=z, value=3
    
  • mapKeys(transform: (Map.Entry<K, V>) -> R): Map<R, V>:把Map的Key設置爲通過轉換函數transform映射之後的值。

    val map:Map<Int,String> = mapOf(1 to "a", 2 to "b", 3 to "c", -1 to "z")
    val mmap = map.mapKeys{it.key * 10}
    mmap	//{10=a, 20=b, 30=c, -10=z}
    
    /**
     * 注意
     * 如果不巧,有任意兩個key通過映射之後相等了,那麼後面的key將會覆蓋掉前面的key。
     **/
    
  • mapValues(transform: (Map.Entry<K, V>) -> R): Map<K, R>:把Map的value設置爲通過轉換函數transform轉換之後的新值。

    val map:Map<Int,String> = mapOf(1 to "a", 2 to "b", 3 to "c", -1 to "z")
    val mmap = map.mapValues({it.value + "$"})
    mmap	//{1=a$, 2=b$, 3=c$, -1=z$}
    
  • filterKeys(predicate: (K) -> Boolean): Map<K, V>:返回過濾出滿足key判斷條件的元素組成的新Map。

    val map:Map<Int,String> = mapOf(1 to "a", 2 to "b", 3 to "c", -1 to "z")
    map.filterKeys({it>0})		//{1=a, 2=b, 3=c}
    
  • filterValues(predicate: (V) -> Boolean): Map<K, V>:返回過濾出滿足value判斷條件的元素組成的新Map。

    val map:Map<Int,String> = mapOf(1 to "a", 2 to "b", 3 to "c", -1 to "z")
    map.filterValues({it>"b"})		//{3=c, -1=z}
    
  • filter(predicate: (Map.Entry<K, V>) -> Boolean): Map<K, V>:返回過濾出滿足Entry判斷條件的元素組成的新Map。

    val map:Map<Int,String> = mapOf(1 to "a", 2 to "b", 3 to "c", -1 to "z")
    map.filter({it.key>0 && it.value > "b"})		//{3=c}
    
  • Iterable<Pair<K, V>>.toMap(destination: M): M:把持有Pair的Iterable集合轉換爲Map。

    val pairList = listOf(Pair(1,"a"),Pair(2,"b"),Pair(3,"c"))
    pairList	//[(1, a), (2, b), (3, c)]
    pairList.toMap()	//{1=a, 2=b, 3=c}
    
  • Map<out K, V>.toMutableMap(): MutableMap<K, V>:把一個只讀的Map轉換爲可編輯的MutableMap。

  • plusminus

    val map = mapOf(1 to "a", 2 to "b", 3 to "c", -1 to "z")
    map+Pair(10,"g")
    //{1=a, 2=b, 3=c, -1=z, 10=g}
    map + listOf(Pair(9,"s"),Pair(10,"w"))
    //{1=a, 2=b, 3=c, -1=z, 9=s, 10=w}
    //map + arrayOf(Pair(9,"s"),Pair(10,"w"))
    {1=a, 2=b, 3=c, -1=z, 9=s, 10=w}
    map + sequenceOf(Pair(9,"s"),Pair(10,"w"))
    //{1=a, 2=b, 3=c, -1=z, 9=s, 10=w}
    map + mapOf(9 to "s", 10 to "w")
    //{1=a, 2=b, 3=c, -1=z, 9=s, 10=w}
    
  • put(key: K, value: V): V?:根據key設置元素的value。如果該key存在就更新value;不存在就添加,但是put的返回值是null。

  • putAll(from: Map<out K, V>): Unit:把一個Map全部添加到一個MutableMap中。

    val map = mutableMapOf(1 to "a", 2 to "b", 3 to "c", -1 to "z")
    val map2 = mapOf(99 to "aa", 100 to "bb")
    map.putAll(map2)
    map	//{1=a, 2=b, 3=c, -1=z, 99=aa, 100=bb}
    
    //如果有key重複的,後面的值會覆蓋掉前面的值。
    
  • MutableMap<out K, V>.remove(key: K): V?:根據鍵值key來刪除元素。

  • MutableMap<K, V>.clear(): Unit:清空MutableMap。

參考資料

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