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
max 、 min :查詢最大、最小的元素,空集則返回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。
plus、 minus:
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極簡教程