kotlin<第五篇>:集合

一、創建集合

創建集合的最常用方法是使用標準庫函數 listOf<T>()setOf<T>()mutableListOf<T>()mutableSetOf<T>()。 如果以逗號分隔的集合元素列表作為參數,編譯器會自動檢測元素類型。創建空集合時,須明確指定類型。

val numbersSet = setOf("one", "two", "three", "four")
val emptySet = mutableSetOf<String>()

Map 也有這樣的函數 mapOf()mutableMapOf()。映射的鍵和值作為 Pair 對象傳遞(通常使用中綴函數 to 創建)。

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key4" to 1)

注意,to 符號創建了一個短時存活的 Pair 對象,因此建議僅在性能不重要時才使用它。為避免過多的內存使用,請使用其他方法。例如,可以創建可寫 Map 并使用寫入操作填充它。 apply()函數可以幫助保持初始化流暢。

val numbersMap = mutableMapOf<String, String>().apply { this["one"] = "1"; this["two"] = "2" }

還有用于創建沒有任何元素的集合的函數:emptyList()emptySet()emptyMap()。 創建空集合時,應指定集合將包含的元素類型。

val empty = emptyList<String>()

具體類型構造函數:

val linkedList = LinkedList<String>(listOf("one", "two", "three"))
val presizedSet = HashSet<Int>(32)

復制:

在特定時刻通過集合復制函數,例如toList()toMutableList()toSet()等等。創建了集合的快照。 結果是創建了一個具有相同元素的新集合 如果在源集合中添加或刪除元素,則不會影響副本。副本也可以獨立于源集合進行更改。

這些函數還可用于將集合轉換為其他類型,例如根據 List 構建 Set:

val sourceList = mutableListOf(1, 2, 3)    
val copySet = sourceList.toMutableSet()
copySet.add(3)
copySet.add(4)    
println(copySet)

過濾:

val numbers = listOf("one", "two", "three", "four")  
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3)
二、迭代器

通過迭代器遍歷集合:

val numbers = listOf("one", "two", "three", "four")
val numbersIterator = numbers.iterator()
while (numbersIterator.hasNext()) {
    println(numbersIterator.next())
}

遍歷 Iterable 集合的另一種方法是眾所周知的 for 循環:

val numbers = listOf("one", "two", "three", "four")
for (item in numbers) {
    println(item)
}

通過forEach遍歷:

val numbers = listOf("one", "two", "three", "four")
numbers.forEach {
    println(it)
}

List 迭代器:

對于列表,有一個特殊的迭代器實現: ListIterator它支持列表雙向迭代:正向與反向。 反向迭代由 hasPrevious()previous()函數實現。 此外, ListIterator 通過 nextIndex()previousIndex()函數提供有關元素索引的信息。

val numbers = listOf("one", "two", "three", "four")
val listIterator = numbers.listIterator()
while (listIterator.hasNext()) listIterator.next()
println("Iterating backwards:")
while (listIterator.hasPrevious()) {
    print("Index: ${listIterator.previousIndex()}")
    println(", value: ${listIterator.previous()}")
}

具有雙向迭代的能力意味著 ListIterator 在到達最后一個元素后仍可以使用。

可變迭代器:

為了迭代可變集合,于是有了 MutableIterator來擴展 Iterator 使其具有元素刪除函數 remove()。因此,可以在迭代時從集合中刪除元素。

val numbers = mutableListOf("one", "two", "three", "four") 
val mutableIterator = numbers.iterator()

mutableIterator.next()
mutableIterator.remove()    
println("After removal: $numbers")

除了刪除元素, MutableListIterator還可以在迭代列表時插入和替換元素。

val numbers = mutableListOf("one", "four", "four") 
val mutableListIterator = numbers.listIterator()

mutableListIterator.next()
mutableListIterator.add("two")
mutableListIterator.next()
mutableListIterator.set("three")   
println(numbers)
三、序列

除了集合之外,Kotlin 標準庫還包含另一種容器類型——序列(Sequence<T>)。 序列提供與 Iterable 相同的函數。

創建序列:

val numbersSequence = sequenceOf("four", "three", "two", "one")

將 Iterable 轉成 Sequence:

val numbers = listOf("one", "two", "three", "four")
val numbersSequence = numbers.asSequence()

基于函數創建無限序列:

val oddNumbers = generateSequence(1) { it + 2 } // 創建無限序列
println(oddNumbers.take(6).toList()) // 取前6個元素,返回長度為6的序列

基于函數創建有限序列:

val oddNumbersLessThan10 = generateSequence(1) { if (it + 2 < 10) it + 2 else null }
println(oddNumbersLessThan10.count())

Iterable 與 Sequence 之間的區別?

Iterable:

val words = "The quick brown fox jumps over the lazy dog".split(" ")
val lengthsList = words.filter { println("filter: $it"); it.length > 3 }
    .map { println("length: ${it.length}"); it.length }
    .take(4)
image.png

Sequence:

val words = "The quick brown fox jumps over the lazy dog".split(" ")
// 將列表轉換為序列
val wordsSequence = words.asSequence()

val lengthsSequence = wordsSequence.filter { println("filter: $it"); it.length > 3 }
    .map { println("length: ${it.length}"); it.length }
    .take(4)
image.png
四、集合轉換

【1】使用映射(map)轉換:

val numbers = setOf(1, 2, 3)
println(numbers.map { it * 3 })
println(numbers.mapIndexed { idx, value -> value * idx })

輸出結果:

[3, 6, 9]
[0, 2, 6]

轉換過程中可能為null,為了防止null值,可用 mapNotNull() 函數取代 map()mapIndexedNotNull() 取代 mapIndexed(),來從結果集中過濾掉 null 值。

val numbers = setOf(1, 2, 3)
println(numbers.mapNotNull { if ( it == 2) null else it * 3 })
println(numbers.mapIndexedNotNull { idx, value -> if (idx == 0) null else value * idx })

輸出結果:

[3, 9]
[2, 6]

映射轉換時,有兩個選擇:轉換鍵,使值保持不變,反之亦然。
要將指定轉換應用于鍵,請使用 mapKeys();反過來,mapValues() 轉換值。 這兩個函數都使用將映射條目作為參數的轉換,因此可以操作其鍵與值。

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
println(numbersMap.mapKeys { it.key.toUpperCase() })
println(numbersMap.mapValues { it.value + it.key.length })

輸出結果:

{KEY1=1, KEY2=2, KEY3=3, KEY11=11}
{key1=5, key2=6, key3=7, key11=16}

【2】使用合攏(zip)轉換

合攏轉換是根據兩個集合中具有相同位置的元素構建配對。

val colors = listOf("red", "brown", "grey")
val animals = listOf("fox", "bear", "wolf")
println(colors zip animals) // 方式一

val twoAnimals = listOf("fox", "bear")
println(colors.zip(twoAnimals)) // 方式二

輸出結果:

[(red, fox), (brown, bear), (grey, wolf)]
[(red, fox), (brown, bear)]

使用帶有兩個參數的轉換函數來調用 zip():

val colors = listOf("red", "brown", "grey")
val animals = listOf("fox", "bear", "wolf")

println(colors.zip(animals) { color, animal -> "The ${animal.capitalize()} is $color"})

輸出結果:

[The Fox is red, The Bear is brown, The Wolf is grey]

使用 unzipping 反向轉換:

val numberPairs = listOf("one" to 1, "two" to 2, "three" to 3, "four" to 4)
println(numberPairs.unzip())

輸出結果:

([one, two, three, four], [1, 2, 3, 4])

【3】使用關聯(associate)轉換

associateWith(原始集合是鍵) :

val numbers = listOf("one", "two", "three", "four")  // 鍵
println(numbers.associateWith { it.length })

輸出結果:

{one=3, two=3, three=5, four=4}

associateBy (原始集合是值):

val numbers = listOf("one", "two", "three", "four") // 值

println(numbers.associateBy { it.first().toUpperCase() })
println(numbers.associateBy(keySelector = { it.first().toUpperCase() }, valueTransform = { it.length }))

輸出結果:

{O=one, T=three, F=four}
{O=3, T=5, F=4}

associate (目標集合的鍵和值都是通過原始集合生成的):

data class FullName (val firstName: String, val lastName: String)

fun parseFullName(fullName: String): FullName {
    val nameParts = fullName.split(" ")
    if (nameParts.size == 2) {
        return FullName(nameParts[0], nameParts[1])
    } else throw Exception("Wrong name format")
}
val names = listOf("Alice Adams", "Brian Brown", "Clara Campbell")
println(names.associate { name -> parseFullName(name).let { it.lastName to it.firstName } })

輸出結果:

{Adams=Alice, Brown=Brian, Campbell=Clara}

【4】使用打平(flat)轉換(將一個集合轉換成另一個集合)

使用 flatten 將嵌套集合轉成非嵌套:

val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
println(numberSets.flatten())

輸出結果:

[1, 2, 3, 4, 5, 6, 1, 2]

合并兩字節數組:

val array1 = UByteArray(1)
array1[0] = 0x01u
val array2 = UByteArray(1)
array2[0] = 0x02u
val array3 = listOf(array1, array2).flatten().toUByteArray().asByteArray()
for (i in array3.indices) {
    print(array3[i].toString() + " ")
}

使用flatMap處理嵌套集合:

data class StringContainer(val values: List<String>)

val containers = listOf(
    StringContainer(listOf("one", "two", "three")),
    StringContainer(listOf("four", "five", "six")),
    StringContainer(listOf("seven", "eight"))
)
println(containers.flatMap { it.values })

輸出結果:

[one, two, three, four, five, six, seven, eight]
五、過濾

根據值過濾:

val numbers = listOf("one", "two", "three", "four")  
val longerThan3 = numbers.filter { it.length > 3 }
println(longerThan3)

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap)

輸出結果:

[three, four]
{key11=11}

根據索引和值來過濾:

val numbers = listOf("one", "two", "three", "four")
val filteredIdx = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5)  }
println(filteredIdx)

輸出結果:

[two, four]

根據否定條件來過濾集合:

val numbers = listOf("one", "two", "three", "four")
val filteredNot = numbers.filterNot { it.length <= 3 }
println(filteredNot)

輸出結果:

[three, four]

根據指定類型過濾:

val numbers = listOf(null, 1, "two", 3.0, "four")
println("All String elements in upper case:")
numbers.filterIsInstance<String>().forEach {
    println(it.toUpperCase())
}

輸出結果:

All String elements in upper case:
TWO
FOUR

過濾所有非空值:

val numbers = listOf(null, "one", "two", null)
numbers.filterNotNull().forEach {
    println(it) 
}

輸出結果:

one
two

通過一個謂詞過濾集合并且將不匹配的元素存放在一個單獨的列表中:

val numbers = listOf("one", "two", "three", "four")
val (match, rest) = numbers.partition { it.length > 3 }

println(match)
println(rest)

輸出結果:

[three, four]
[one, two]

檢驗謂詞:

val numbers = listOf("one", "two", "three", "four")

println(numbers.any { it.endsWith("e") })  // 至少有一個元素匹配給定謂詞
println(numbers.none { it.endsWith("a") }) // 沒有元素與給定謂詞匹配
println(numbers.all { it.endsWith("e") }) // 所有元素都匹配給定謂詞
六、加減操作符

在 Kotlin 中,為集合定義了 plus (+) 和 minus(-) 操作符。它們均為重載操作符, plus對應著+minus對應著-

val numbers = listOf("one", "two", "three", "four")

val plusList = numbers + "five"
val minusList = numbers - listOf("three", "four")
println(plusList)
println(minusList)

輸出結果:

[one, two, three, four, five]
[one, two]
七、分組

基本函數 groupBy() 使用一個 lambda 函數并返回一個 Map,在此 Map 中,每個鍵都是 lambda 結果,而對應的值是返回此結果的元素 List。

按大寫首字母分組:

val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.groupBy { it.first().toUpperCase() })

輸出結果:

{O=[one], T=[two, three], F=[four, five]}

按首字母分組,并將值轉成大寫:

val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.toUpperCase() }))

輸出結果:

{o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}

如果要多具體的元素進行分組,可以使用groupingBy:

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.groupingBy { it.first() }.eachCount())

輸出結果:

{o=1, t=2, f=2, s=1}

groupingBy 返回Grouping類型,Grouping有 foldreduce 函數。

foldreduce

它們的區別是?

reduce的返回值類型必須和集合的元素類型相符。
fold的返回值類型則不受約束。

通過 reduce 實現元素求和:

val numbers = listOf(2, 5, 1)
val result = numbers.reduce { a: Int, b: Int -> a + b }
println("reduceResult=$result")

輸出結果:

reduceResult=8

通過 fold 將集合拼接成字符串:

val numbers = listOf(2, 5, 1)
val result = numbers.fold(StringBuilder()) {
        str: StringBuilder, i: Int -> str.append(i).append(" ")
}
println("foldResult=$result")

輸出結果:

foldResult=2 5 1 

---------------------------

fold : 合攏,折疊
reduce : 壓縮
兩個函數都是對集合的遍歷,只是遍歷完成之后能得到一個結果。
折疊和壓縮的意思,可以理解為,將集合折疊成一個新的對象【對象的類型,可以與集合元素的類型無關】
或者壓縮成一個值【類型必須和集合元素的類型一致】。
八、取集合中的一部分

【1】使用 Slice 返回具有給定索引的集合元素列表

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.slice(1..3))
println(numbers.slice(0..4 step 2))
println(numbers.slice(setOf(3, 5, 0)))

輸出結果:

[two, three, four]
[one, three, five]
[four, six, one]

【2】使用Take 與 drop

take:從頭開始獲取指定數量的元素
drop:從頭開始去除指定數量的元素
takeLast:從尾開始獲取指定數量的元素
dropLast:從尾開始去除指定數量的元素

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.take(3))
println(numbers.takeLast(3))
println(numbers.drop(1))
println(numbers.dropLast(5))

輸出結果:

[one, two, three]
[four, five, six]
[two, three, four, five, six]
[one]

使用謂詞來定義要獲取或去除的元素的數量(takeWhile 、takeLastWhile、dropWhile、dropLastWhile):

 val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.takeWhile { !it.startsWith('f') })
println(numbers.takeLastWhile { it != "three" })
println(numbers.dropWhile { it.length == 3 })
println(numbers.dropLastWhile { it.contains('i') })

輸出結果:

[one, two, three]
[four, five, six]
[three, four, five, six]
[one, two, three, four]

【3】使用 chunked 將集合分解成給定大小的"塊"

val numbers = (0..13).toList()
println(numbers.chunked(3))

輸出結果:

[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]

還可以返回塊的轉換:

val numbers = (0..13).toList() 
println(numbers.chunked(3) { it.sum() })  // `it` 為原始集合的一個塊

輸出結果:

[3, 12, 21, 30, 25]

【4】使用 Windowed 檢索給定大小的集合元素中所有可能區間

val numbers = listOf("one", "two", "three", "four", "five")    
println(numbers.windowed(3))

輸出結果:

[[one, two, three], [two, three, four], [three, four, five]]

windowed()有兩個參數:step 、partialWindows
step:間隔
partialWindows:是否包含較小的窗口

val numbers = (1..10).toList()
println(numbers.windowed(3, step = 2, partialWindows = true))
println(numbers.windowed(3, step = 2, partialWindows = false))

輸出結果:

[[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9], [9, 10]]
[[1, 2, 3], [3, 4, 5], [5, 6, 7], [7, 8, 9]]

還可以返回塊的轉換:

val numbers = (1..10).toList()
println(numbers.windowed(3) { it.sum() })

輸出結果:

[6, 9, 12, 15, 18, 21, 24, 27]

【5】使用 zipWithNext 創建接收器集合的相鄰元素對

val numbers = listOf("one", "two", "three", "four", "five")    
println(numbers.zipWithNext())
println(numbers.zipWithNext() { s1, s2 -> s1.length > s2.length})

輸出結果:

[(one, two), (two, three), (three, four), (four, five)]
[false, false, true, false]
九、取單個元素

【1】按位置取

val numbers = linkedSetOf("one", "two", "three", "four", "five")
println(numbers.elementAt(3))    // 相當于numbers[3]

輸出結果:

four

排序或獲取單個元素:

val numbersSortedSet = sortedSetOf("one", "two", "three", "four")
println(numbersSortedSet)  
println(numbersSortedSet.elementAt(0)) // 相當于numbers[0]

輸出結果:

[four, one, three, two]
four

使用 first 和 last 獲取單個元素:

val numbers = listOf("one", "two", "three", "four", "five")
println(numbers.first())    
println(numbers.last())    

輸出結果:

one
five

具有安全性質獲取單個元素(防止空指針和角標越界引起的崩潰):

val numbers = listOf("one", "two", "three", "four", "five")

println(numbers.elementAtOrNull(5)) // 相當于 numbers.getOrNull(5)
println(numbers.elementAtOrElse(5) { index -> "The value for index $index is undefined"}) // 相當于 numbers.getOrElse()

輸出結果:

null
The value for index 5 is undefined

【2】按條件取

使用 first 、last 按條件獲取:

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.first { it.length > 3 })
println(numbers.last { it.startsWith("f") })

輸出結果:

three
five

為了避免空指針導致的異常,可以使用 firstOrNull、 lastOrNull 代替:

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.firstOrNull { it.length > 6 })
println(numbers.lastOrNull { it.length > 6 })

輸出結果:

null
null

使用 find 和 findLast 按條件獲取:

val numbers = listOf(1, 2, 3, 4)
println(numbers.find { it % 2 == 0 })
println(numbers.findLast { it % 2 == 0 })

輸出結果:

2
4

【3】隨機取元素

val numbers = listOf(1, 2, 3, 4)
println(numbers.random())

【4】檢測存在與否

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.contains("four"))
println("zero" in numbers)

println(numbers.containsAll(listOf("four", "two")))
println(numbers.containsAll(listOf("one", "zero")))

輸出結果:

true
false
true
false

【5】檢查集合中是否為空或非空

val numbers = listOf("one", "two", "three", "four", "five", "six")
println(numbers.isEmpty())
println(numbers.isNotEmpty())

val empty = emptyList<String>()
println(empty.isEmpty())
println(empty.isNotEmpty())

輸出結果:

false
true
true
false
十、排序

【1】實現 Comparable 接口自定義比較規則,并排序:

class Version(val major: Int, val minor: Int): Comparable<Version> {
    override fun compareTo(other: Version): Int {
        if (this.major != other.major) {
            return this.major - other.major
        } else if (this.minor != other.minor) {
            return this.minor - other.minor
        } else return 0
    }

    override fun toString(): String {
        return "($major,$minor)"
    }
}

var list = arrayListOf(Version(1, 2), Version(1, 3), Version(2, 0), Version(1, 5))
list.sort()
println(list)

輸出結果:

[(1,2), (1,3), (1,5), (2,0)]

【2】還可以使用 Comparator 對象排序:

val versionComparator = Comparator<Version> { version1: Version, version2: Version ->
    if (version1.major != version2.major) {
        version1.major - version2.major
    } else if (version1.minor != version2.minor) {
        version1.minor - version2.minor
    } else 0}

var list = arrayListOf(Version(1, 2), Version(1, 3), Version(2, 0), Version(1, 5))
list.sortWith(versionComparator)
println(list)

輸出結果:

[(1,2), (1,3), (1,5), (2,0)]

【3】自然排序

sorted(): 升序排序
sortedDescending():降序排序

val numbers = listOf("one", "two", "three", "four")

println("Sorted ascending: ${numbers.sorted()}")
 println("Sorted descending: ${numbers.sortedDescending()}")

輸出結果:

Sorted ascending: [four, one, three, two]
Sorted descending: [two, three, one, four]

集合的元素都是字符串,字符串的自然順序是比較字符串的大小。

【4】使用 sortedBy 自定義一個自然順序

val numbers = listOf("one", "two", "three", "four")

val sortedNumbers = numbers.sortedBy { it.length }
println("Sorted by length ascending: $sortedNumbers")
val sortedByLast = numbers.sortedByDescending { it.last() }
println("Sorted by the last letter descending: $sortedByLast")

輸出結果:

Sorted by length ascending: [one, two, four, three]
Sorted by the last letter descending: [four, two, one, three]

【5】倒序排序

val numbers = listOf("one", "two", "three", "four")
println(numbers.reversed())

輸出結果:

[four, three, two, one]

【6】隨機順序

val numbers = listOf("one", "two", "three", "four")
println(numbers.shuffled())
十一、集合聚合操作

集合聚合操作:基于集合內容返回單個值的操作

使用 count、max、min、average、sum函數:

val numbers = listOf(6, 42, 10, 4)

println("Count: ${numbers.count()}")
println("Max: ${numbers.max()}")
println("Min: ${numbers.min()}")
println("Average: ${numbers.average()}")
println("Sum: ${numbers.sum()}")

輸出結果:

Count: 4
Max: 42
Min: 4
Average: 15.5
Sum: 62

使用 minBy 、maxBy 、maxWith、minWith:

val numbers = listOf(5, 42, 10, 4)
val minRemainder = numbers.minBy { it % 3 }
println(minRemainder)
val maxRemainder = numbers.maxBy { it % 3 }
println(maxRemainder)
val strings = listOf("one", "two", "three", "four")
val maxLengthString = strings.maxWith(compareBy { it.length })
println(maxLengthString)
val minLengthString = strings.minWith(compareBy { it.length })
println(minLengthString)

輸出結果:

42
5
three
one

使用高級求和函數sumBy 、sumByDouble:

val numbers = listOf(5, 42, 10, 4)
println(numbers.sumBy { it * 2 })
println(numbers.sumByDouble { it.toDouble() / 2 })

輸出結果:

122
30.5
十二、集合寫操作

【1】添加元素

add:

val numbers = mutableListOf(1, 2, 3, 4)
numbers.add(5)
println(numbers)

輸出結果:

[1, 2, 3, 4, 5]

addAll:

val numbers = mutableListOf(1, 2, 5, 6)
numbers.addAll(arrayOf(7, 8))
println(numbers)
numbers.addAll(2, setOf(3, 4))
println(numbers)

輸出結果:

[1, 2, 5, 6, 7, 8]
[1, 2, 3, 4, 5, 6, 7, 8]

使用 plus 運算符 (-) 和 plusAssign (+=) 添加元素:

val numbers = mutableListOf("one", "two")
numbers += "three"
println(numbers)
numbers += listOf("four", "five")    
println(numbers)

輸出結果:

[one, two, three]
[one, two, three, four, five]

【2】刪除元素

val numbers = mutableListOf(1, 2, 3, 4, 3)
numbers.remove(3) // 刪除

numbers.retainAll { it >= 3 } // 保留

numbers.clear() // 清空

val numbersSet = mutableSetOf("one", "two", "three", "four")
numbersSet.removeAll(setOf("one", "two")) // 刪除所有
十三、List相關操作

【1】按索引取元素

val numbers = listOf(1, 2, 3, 4)
println(numbers.get(0))
println(numbers[0])

println(numbers.getOrNull(5))  
println(numbers.getOrElse(5, {it})) 

【2】取列表的一部分

val numbers = (0..13).toList()
println(numbers.subList(3, 6))

輸出結果:

[3, 4, 5]

【3】查找元素位置

線性查找:

val numbers = listOf(1, 2, 3, 4, 2, 5)
println(numbers.indexOf(2))
println(numbers.lastIndexOf(2))

val numbers = mutableListOf(1, 2, 3, 4)
println(numbers.indexOfFirst { it > 2})
println(numbers.indexOfLast { it % 2 == 1})

在有序列表中二分查找:

val numbers = mutableListOf("one", "two", "three", "four")
numbers.sort()
println(numbers)
println(numbers.binarySearch("two")) 
println(numbers.binarySearch("z")) 
println(numbers.binarySearch("two", 0, 2)) 

Comparator 二分搜索:

data class Product(val name: String, val price: Double)

fun main() {
    val productList = listOf(
        Product("WebStorm", 49.0),
        Product("AppCode", 99.0),
        Product("DotTrace", 129.0),
        Product("ReSharper", 149.0))

    println(productList.binarySearch(Product("AppCode", 99.0), 
    compareBy<Product> { it.price }.thenBy { it.name }))
}

使用 String.CASE_INSENSITIVE_ORDER:

val colors = listOf("Blue", "green", "ORANGE", "Red", "yellow")
println(colors.binarySearch("RED", String.CASE_INSENSITIVE_ORDER)) 

比較函數二分搜索:

data class Product(val name: String, val price: Double)

fun priceComparison(product: Product, price: Double) = sign(product.price - price).toInt()

fun main() {
    val productList = listOf(
        Product("WebStorm", 49.0),
        Product("AppCode", 99.0),
        Product("DotTrace", 129.0),
        Product("ReSharper", 149.0))

    println(productList.binarySearch { priceComparison(it, 99.0) })
}

【4】添加

val numbers = mutableListOf("one", "five", "six")
numbers.add(1, "two")
numbers.addAll(2, listOf("three", "four"))
println(numbers)

【5】更新

val numbers = mutableListOf("one", "five", "three")
numbers[1] =  "two"
println(numbers)

【6】替換

val numbers = mutableListOf(1, 2, 3, 4)
numbers.fill(3) // 將所有元素替換成指定值
println(numbers)

輸出結果:

[3, 3, 3, 3]

【7】刪除

val numbers = mutableListOf(1, 2, 3, 4, 3)    
numbers.removeAt(1)
println(numbers)

val numbers = mutableListOf(1, 2, 3, 4, 3)    
numbers.removeFirst()
numbers.removeLast()
println(numbers)

val empty = mutableListOf<Int>()
// empty.removeFirst() // NoSuchElementException: List is empty.
empty.removeFirstOrNull() //null

【8】排序

val numbers = mutableListOf("one", "two", "three", "four")

numbers.sort()
println("Sort into ascending: $numbers")
numbers.sortDescending()
println("Sort into descending: $numbers")

numbers.sortBy { it.length }
println("Sort into ascending by length: $numbers")
numbers.sortByDescending { it.last() }
println("Sort into descending by the last letter: $numbers")

numbers.sortWith(compareBy<String> { it.length }.thenBy { it })
println("Sort by Comparator: $numbers")

numbers.shuffle() // 隨機
println("Shuffle: $numbers")

numbers.reverse() // 反轉
println("Reverse: $numbers")

輸出結果:

Sort into ascending: [four, one, three, two]
Sort into descending: [two, three, one, four]
Sort into ascending by length: [two, one, four, three]
Sort into descending by the last letter: [four, two, one, three]
Sort by Comparator: [one, two, four, three]
Shuffle: [two, one, three, four]
Reverse: [four, three, one, two]
十四、Set相關操作
val numbers = setOf("one", "two", "three")

println(numbers union setOf("four", "five")) // 并集
println(setOf("four", "five") union numbers) // 并集

println(numbers intersect setOf("two", "one")) // 交集
println(numbers subtract setOf("three", "four")) // 差集
println(numbers subtract setOf("four", "three")) // 差集

輸出結果:

[one, two, three, four, five]
[four, five, one, two, three]
[one, two]
[one, two]
[one, two]
十五、Map相關操作

【1】取鍵與值

val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.get("one"))
println(numbersMap["one"])
numbersMap.getOrElse("four") {"錯誤"}
println(numbersMap.getOrDefault("four", 10))


val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap.keys)
println(numbersMap.values)

【2】過濾

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredMap = numbersMap.filter { (key, value) -> key.endsWith("1") && value > 10}
println(filteredMap)

val numbersMap = mapOf("key1" to 1, "key2" to 2, "key3" to 3, "key11" to 11)
val filteredKeysMap = numbersMap.filterKeys { it.endsWith("1") }
val filteredValuesMap = numbersMap.filterValues { it < 10 }

println(filteredKeysMap)
println(filteredValuesMap)

【3】plus 與 minus 操作

val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap + Pair("four", 4))
println(numbersMap + Pair("one", 10))
println(numbersMap + mapOf("five" to 5, "one" to 11))

val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
println(numbersMap - "one")
println(numbersMap - listOf("two", "four"))

【4】添加與更新

val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap.put("three", 3)
println(numbersMap)

val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.putAll(setOf("four" to 4, "five" to 5))
println(numbersMap)

【5】plusAssign+=) 操作符

val numbersMap = mutableMapOf("one" to 1, "two" to 2)
numbersMap["three"] = 3     // 調用 numbersMap.set("three", 3)
numbersMap += mapOf("four" to 4, "five" to 5)
println(numbersMap)

【6】刪除

val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap.remove("one")
println(numbersMap)
numbersMap.remove("three", 4)            //不會刪除任何條目
println(numbersMap)

val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3, "threeAgain" to 3)
numbersMap.keys.remove("one")
println(numbersMap)
numbersMap.values.remove(3)
println(numbersMap)

使用 minusAssign-=) 操作符:

val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
numbersMap -= "two"
println(numbersMap)
numbersMap -= "five"             //不會刪除任何條目
println(numbersMap)

[本章完...]

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容