当前位置: 首页 > article >正文

Kotlin 语言基础语法及标准库

基础

Kotlin 变量和数据类型

不可变变量 val关键字

类似java中final关键字,必须有初始值,且不更改变量的值

Error:(13, 5) Kotlin: Val cannot be reassigned

可变变量var 关键字

var myName = "china"

类型推断

// 没有指定变量类型,编译器自动判断类型为String
var website = "hello world"   

 // 指定变量类型
var website: String = "hello world"  

// 先声明,后初始化值
var website: String
website = "hello world"

基础数据类型

  1. 数字:ByteShortLongIntFloatDouble
  2. Boolean : true/false
  3. Char
  4. Array
  5. String

Byte

fun main(args : Array) {
    val num: Byte = 99
    println("$num")

    // 127
    var bigByte: Byte = Byte.MAX_VALUE
    // -128
    var smallByte: Byte = Byte.MIN_VALUE
}


Short

fun main(args : Array) {
    val num: Short = 29999
    println("$num")
}

Int

fun main(args : Array) {
    val num: Int = 123456
    println("$num")
}

Long

fun main(args : Array) {
    val num: Long = 12345678
    println("$num")
}

Double

fun main(args : Array) {
    val num = 101.99
    println("$num")
}

Float

fun main(args : Array) {
    val num = 101.99F
    println("$num")
}

Boolean

fun main(args : Array) {
    val boolValue = false
    println("$boolValue")
}

Char

fun main(args : Array) {
    val ch = 'A'
    println("ch")

    val ch2: Char
    ch2 = 'Z'
    println("ch2")
}

类型转换函数

  • toChar()
  • toInt()
  • toLong()
  • toFloat()
  • toDouble()
  • toByte()
  • toShort()

fun main(args : Array<String>){

    println("4.554 to int: " + (4.554.toInt()))
    
    println("66 to Char: " + (65.toChar()))

    println("B to int: " + ('B'.toInt()))
}

String 字符串

// 常量字符串
val website = "BeginnersBook"

// """ """ 模版字符串
val longString = """Welcome to
        Beginnersbook.com"""


// $变量
var name = "hello"
var name2 = "world"
name = name + " "+ name2
println("name is : $name")

获取字符串长度

.length

var name = "hello"

println("name length is : ${name.length}")
println("name length is :" + name.length)

字符串比较

equals()

compareTo()

fun main(args : Array<String>){

    var str1 = "BeginnersBook"
    var str2 = "beginnersbook"

    // true 相同
    println("String Equals? : "+ str1.equals(str2))
    // == 0 相同  
    println("String Equals? :"+ str1.compareTo(str2) == 0 )
}

获取指定下标字符

.get(index)

截取子串

.subSequence(fromIndex,toIndex)

  • fromIndex 包含
  • toIndex 排它

字符串是否包含

.contains()


数组

声明

arrayOf

  • 包含多种类型
var arr = arrayOf(10,"hello",'h')
  • 单个类型
var arr = arrayOf<Int>(1,2,3,4)

var arr = arrayOf<String>("A","B","C")

获取下标元素值

arr[index]

设置下标元素值

array[index] = 3

数组大小

.size

元素包含

.contains

范围 Range

for(num in 1..4){
    println(num)
}


for(ch in 'A'..'E'){
    println(ch)
}

判断元素值是否在范围内

in

fun main(args: Array<String>) {
    val oneToTen = 1..10
    print(3 in oneToTen)
}

顺序递增/递减

.rangeTo() 递增

.downTo() 递减

val oneToFive = 1.rangeTo(5)   // 1,2,3,4,5
val sixToThree = 6.downTo(3)   // 6,5,4,3

指定步长

.step()

val oneToTen = 1..10
// 1,3,5,7,9    
val odd = oneToTen.step(2)  // 1-10的数 自增2

条件 表达式

if

if ... else

if ... else if .. else

when 表达式

类似Java中的switch case 语法

fun main(){

    var ch = 'A'

    when(ch){

        'A' -> println("A is a Vowel")
        'E' -> println("E is a Vowel")
        'I' -> println("I is a Vowel")
        'O' -> println("O is a Vowel")
        'U','Z' -> println("U Z Hello")

        else -> println("$ch is a Consonant")
    }
}

也可以结合范围来判断

var num = 78

when(num) {
    in 1..9 -> println("num is a single digit number")
    in 10..99 -> println("num is a two digit number")
    in 100..999 -> println("num is a three digit number")
    else -> println("num has more than three digits")
}

For 循环

fun main(){

    // 正常循环
    val myArray = arrayOf("ab", "bc", "cd", "da")
    for (str in myArray){
        println(str)
    }

    // 带索引下标的循环
    val myArray = arrayOf("Steve", "Robin", "Kate", "Lucy")
    for((index, value) in myArray.withIndex()){
        println("Value at ${index} index is: ${value}")
    }
}

While 循环

while()

fun main(){
    var num = 10
    
    while(num>=5){
        println("Loop: $num")
        num--
    }
}

do while 循环

do{} while() 至少循环一次。

fun main(){

    var num = 100
    do {
        println("Loop: $num")
        num++
    }
    while (num<=105)
}

break 终止外循环

xxx@

break @xxx

fun main(){

    myloop@ for(ch in 'A'..'C'){
        for (n in 1..4){
            println("ch andn")
            if(n==2)
                break @myloop
        }
    }
}

标准库

集合

概述

集合接口相关函数位于 ktolin.collections 包中,Kotlin相关的集合类型包含有:List(有序集合),Set(唯一集合),Map(key-value键值对)。

集合的构造

创建集合最常用的办法是使用过标准库函数:listOf<T>()setOf<T>()mutableListOf<T>()mutableSetOf<T>()。如果是以逗号分割的集合元素列表作为参数,编译器会自动检测元素的类型。创建空集合时,必须明确指定类型。

  • listOf<T>()setOf<T>()mapOf<T>() 只读,提供元素访问的操作
    • 当修改时编译器会报错:No set method providing array access(没有提供数组访问的设置方法)
  • mutableListOf<T>()mutableListOf<T>()mutableMapOf<T>() 可变,提供添加、删除,更新其元素的操作
var numberSet = setOf("one","two")
var emptySet = mutableSetOf<String>()

Map也有同样的函数:mapOf() 与 mutableMapOf()

var numbersMap = mapOf("k1" to 1,"k2" to 2)

映射的键和值作为Pair对象传递,通常使用中缀函数to创建:to 符号创建一个短时存活的Pair对象,性能会受影响,可以创建可以写Map并使用apply() 函数来保持初始化的流畅。

var numbersMap = mutableMapOf<String,String>().apply {
    this["k1"] = "1";
    this["k2"] = "2"
}

buildListbuildSetbuildMap 也可以快速构造集合

val list = buildList<String> { add("one"); add("two") }
println(list)

val set = buildSet<String> { add("one"); add("two") }
println(set)

val map  =buildMap<String, String> { put("a", "1"); put("b", "2") }
println(map)
空集合

emptyList()emptySet()emptyMap()创建空集合时,应指定集合将包含的元素类型。

val empty = emptyList<String>()
复制

要创建与现有集合具有相同元素的集合,可以使用复制的操作。可以使用toList()toMutableList()toSet()等。创建了集合的快照,结果是创建了一个具有相同元素的新集合,如果在源集合中添加或删除元素,则不会影响副本,副本也可以独立于源集合进行更改。

toList复制出一个readOnly

toMutableList复制出一个可以添加,删除,编辑的集合

fun main() {

    val sourceList = mutableListOf("1", "2", "3", "4", "5")
    val copySourceList = sourceList.toMutableList()
    println("source:" + sourceList)
    println("copy object:" + copySourceList)

    println("---------------")
    sourceList.add("6")
    println("source:" + sourceList)
    println("copy object:" + copySourceList)

    println("---------------")
    copySourceList.add("7")
    println("source:" + sourceList)
    println("copy object:" + copySourceList)

}



source:[1, 2, 3, 4, 5]
copy object:[1, 2, 3, 4, 5]
---------------
source:[1, 2, 3, 4, 5, 6]
copy object:[1, 2, 3, 4, 5]
---------------
source:[1, 2, 3, 4, 5, 6]
copy object:[1, 2, 3, 4, 5, 7]

迭代器

Iterable<T>接口的继承者(包括SetList)可以通过调用iterator()函数获得迭代器。一旦获得迭代器它就指向集合的第一个元素;调用next()函数将返回此元素,并将迭代器指向下一个元素(如果下一个元素存在)。一旦迭代器通过了最后一个元素,它就不能再用于检索元素,也无法重新指向到以前的任何位置,要再次遍历集合,请创建一个新的迭代器。

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

遍历 Iterable集合的另一种方法只for循环。

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

forEeach

fun main() {
    val numbers = listOf("one", "two", "three", "four")
    numbers.forEach {
        println(it)
    }
}
可变迭代器

为了迭代可变集合,于是有了 [MutableIterator](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-iterator/index.html) 来扩展 Iterator 使其具有元素删除函数 [remove()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-iterator/remove.html) 。因此,可以在迭代时从集合中删除元素。

fun main() {
    val numbers = mutableListOf("one", "two", "three", "four") 
    val mutableIterator = numbers.mutableIterator()

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


[one, two, three, four]

区间与数列

Kotlin 可通过调用 kotlin.ranges 包中的 rangeTo函数以及操作符形式的…轻松的创建两个值的区间。

  • i in 1…4 等同于 i >=1 && i <= 4
fun main(){
    for (i in 1..4)    
        println(i)
}


1,2,3,4
  • 如果要反向迭代数字,请使用 downTo 函数
fun main(){
    for (i in 4 downTo 1)    
        println(i)
}

4,3,2,1
  • 默认通过任意步长(不一定为1)迭代数字,请使用step函数
fun main() {
    for (i in 1..8 step 2)
        println(i)
}

1,3,5,7
fun main(){
    for (i in 10 downTo 1 step 3)
        println(i)
}

10,7,3,1
  • 迭代不包含结束元素,请使用 until 函数

fun main(){
    for (i in 1 until  5)
        println(i)
}

1,2,3,4

集合的操作

Ktolin 标准库提供了用于对集合执行操作的多种函数,这包括简单的操作,例如获取、添加元素,以及更复杂的操作,包括搜索,排序,过滤,转换等。

集合转换

Kotlin 标准库为集合转换提供一组扩展函数,这些函数根据提供的转换规则从现有的集合中构建新的集合。

映射
map

映射转换从另一个集合的元素上的函数结果创建一个集合,基本的映射函数是map(),它将给定的lambda函数应用于每个后续元素,并返回lambda结果列表,结果的顺序与元素的原始顺序相同。如需应用还要用到元素索引作为参数的转换,请使用 mapIndexed()

fun main() {
    val list = listOf(1, 2, 3, 4, 5)
    val mapList = list.map { it -> it + 1 }
    println(mapList)  // [2, 3, 4, 5, 6]

    mapList.mapIndexed { idx, it ->
        println("下标:$idx:元素值:$it")
    }
    
// 下标:0:元素值:2
// 下标:1:元素值:3
// 下标:2:元素值:4
// 下标:3:元素值:5
// 下标:4:元素值:6
}
mapNotNull

如果在转换某些元素上产生null值,则可以通过mapNotNull() 函数来取代

fun main(){
val listOfNull = listOf(1, 2, 3, 4, 5, 6)
val listOfNullMap = listOfNull.mapNotNull { it -> if(it%2 ==0 ) null else it + 100}
println(listOfNullMap) // [101, 103, 105]
}
mapKeys / mapValues

Map集合映射转换时,有两个选择, 转换键,使值保持不变,反之亦然。

转换键 : mapKeys

转换值:mapValues

fun main() {
    val map = buildMap<String, Int> {
        put("k1", 1)
        put("k2", 2)
        put("k3", 3)
        put("k4", 5)
    }

    // 将key的值统一大写
    val keyUppercaseMap = map.mapKeys { item -> item.key.uppercase() }
    println(keyUppercaseMap) // {K1=1, K2=2, K3=3, K4=5}

    // 将value的值乘以2
    val valueDoubleMap = map.mapValues { item -> item.value * 2 }
    println(valueDoubleMap) // {k1=2, k2=4, k3=6, k4=10}

}
双路合并
zip

双路合并转换时根据两个集合中具有相同位置的元素构建配对。通过 zip 扩展函数完成。在一个集合(或数组)上以另一个集合(或数组)作为参数调用,zip函数返回Pair对象的列表。如果集合的大小不同,则zip() 函数的结果为较小集合的大小;结果中不包含较大集合的后续元素,zip()也可以中缀形式调用 a zip b.

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

    val zipData = colors zip animals

    println(zipData) // [(red, fox), (brown, bear), (grey, wolf)]

    for ((color, animal) in zipData) {
        println("The $color $animal is very fast.")
    }
    
  }
  • 如果集合中元素大小不匹配,则返回小的集合匹配结果
fun main(){
    val colors1 = listOf("red", "brown", "grey")
    val animals1 = listOf("fox", "bear")
    
    val zipData1 = colors1 zip animals1
    
    println(zipData1) // [(red, fox), (brown, bear)]

}
unzip

如果要分割键值对列表,请调用 unzip

fun main(){
    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])
}
关联
associateWith

基本的关联函数 associateWith 创建一个map,其中原始集合的元素是键,并通过给定的转换函数从中产生值。

fun main() {
    val numbers = listOf("one", "two", "three", "four")
    val numbersMap = numbers.associateWith { it.length }
    println(numbersMap) // {one=3, two=3, three=5, four=4}
}
associateBy

为了使用集合元素作为值来构建Map,请使用函数 associateBy()

fun main(){
    val numbersMap1 = numbers.associateBy { it -> it.first().uppercase() }
    println(numbersMap1)  // {O=one, T=three, F=four}
}
associate

另外一种构建Map的方法是使用函数 associate(), 其中Map键和值都是通过集合元素生成的,他需要一个lambda函数,该函数返回的Pair:键和相应Map条目的的值

注意:该函数会生成临时的Pair对象,可能会影响性能。

fun main(){
    val fullNameList = listOf("Alice Adams", "Brian Brown", "Clara Campbell")
    val fullNameListMap = fullNameList.associate { name -> name.split(" ")[0]
                            .let { it to name.split(" ")[1] } }
    println(fullNameListMap)  // {Alice=Adams, Brian=Brown, Clara=Campbell}
}
打平
flatten

如需操作嵌套的集合,可以在一个集合的集合(一个Set组成的List)上调用它,该函数可以返回嵌套集合中的所有元素的一个List。

fun main(){
    val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
    val flatten = numberSets.flatten()
    println(flatten)  // [1, 2, 3, 4, 5, 6, 1, 2]
}
flatMap

该函数也提供一种灵活的方式来处理嵌套的集合,它需要一个函数将一个集合元素映射到另一个集合,因此flatMap返回单个列表其中包含所有的元素值,所以 flatMap 表现为map与flatten的连续调用。

fun main(){
    val numberSets = listOf(setOf(1, 2, 3), setOf(4, 5, 6), setOf(1, 2))
    val flatMap = numberSets.flatMap { it }
    println(flatMap) // [1, 2, 3, 4, 5, 6, 1, 2]
}
字符串表示
joinToString

joinToString函数根据提供的参数从集合元素构建单个String.

fun main() {
    val numbers = listOf("he", "llo", "w", "orld")
    val numbersStr = numbers.joinToString()
    println(numbersStr) // he, llo, w, orld
}

要构建自定义字符串表示形式,可以在函数参数 separatorprefixpostfix中指定其参数。 结果字符串将以 prefix 开头,以 postfix 结尾。除最后一个元素外,separator 将位于每个元素之后。

fun main() {
    val numbers = listOf("one", "two", "three", "four")    
    // start: one | two | three | four: end    
    println(numbers.joinToString(separator = " | ", prefix = "start: ", postfix = ": end"))
    
}

对于较大的集合,可能需要指定 limit ——将包含在结果中元素的数量。 如果集合大小超出 limit,所有其他元素将被 truncated 参数的单个值替换。

fun main() {
    val numbers = (1..100).toList()
    // 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, <...>
    println(numbers.joinToString(limit = 10, truncated = "<...>"))
}

最后,要自定义元素本身的表示形式,请提供 transform 函数

fun main() {//sampleStart
    val numbers = listOf("one", "two", "three", "four")
    // Element: ONE, Element: TWO, Element: THREE, Element: FOUR
    println(numbers.joinToString { "Element: ${it.toUpperCase()}"})
}
joinTo

执行相同的操作,但将结果附加到给定的 Appendable对象

fun main(){
    val numbers2 = listOf("one", "two", "three", "four")
    val listString = StringBuffer("The list of numbers: ")
    numbers2.joinTo(listString)
    println(listString)  // The list of numbers: one, two, three, four
}
过滤

过滤条件由谓词定义-接受一个集合元素并且返回布尔值的lambda表达式,其返回值含义:true说明给定元素与谓词匹配,false 则表示不匹配。

filter

filter() 返回与其匹配的集合元素,对于List和Set,过滤结果都是一个List,对Map来讲结果还是Map。

fun main() {
    val numbers = listOf("one", "two", "three", "four")
    val longerThan3 = numbers.filter { it.length > 3 }
    // [three, four]
    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 }
    // {key11=11}
    println(filteredMap)
}

filter()中谓词只能检查元素的值,如果想在过滤中使用元素在集合中的位置,应该使用filterIndexed(),他接受一个带有两个参数的谓词:元素的索引和元素的值。

filterNot

如果想使用否定条件来过滤集合,请使用 filterNot . 它返回一个让谓词产生false的元素列表

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

    val filteredIdx = numbers.filterIndexed { index, s -> (index != 0) && (s.length < 5) }
    val filteredNot = numbers.filterNot { it.length <= 3 }

    // [two, four]
    println(filteredIdx)
    // [three, four]
    println(filteredNot)
}
filterIsInstance

过滤给定类型的元素

fun main() {
      val numbers = listOf(null, 1, "two", 3.0, "four")
      // TWO FOUR
      numbers.filterIsInstance<String>().forEach {
          println(it.uppercase())
      }
  }
filterNotNull

返回所有的非空元素

fun main() {
    val numbers = listOf(null, "one", "two", null)
    val numberNotNullList = numbers.filterNotNull();
    // [one, two]
    println(numberNotNullList)
}
划分
partiton

另一个过滤函数 – [partition()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/partition.html) – 通过一个谓词过滤集合并且将不匹配的元素存放在一个单独的列表中。因此,你得到一个 ListPair 作为返回值:第一个列表包含与谓词匹配的元素并且第二个列表包含原始集合中的所有其他元素。

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

    println(match)  // [three, four]
    println(rest)  // [one, two]
}
校验谓词
any

如果至少有一个元素匹配给定的谓词,那么any()返回true

none

如果没有元素与给定谓词匹配,那么none()返回true

all

如果所有的元素都匹配给定谓词,那么all()返回true,在一个空集合上使用任何有效的谓词去调用all()都会返回true

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

    println(numbers.any { it.endsWith("e") })  // true
    println(numbers.none { it.endsWith("a") }) // true
    println(numbers.all { it.endsWith("e") }) // false

    println(emptyList<Int>().all { it > 5 }) // true
}
加减操作符

在kotlin中,为集合定义了plus(+) 和minus(-)操作符;

  • plus 的结果包含原始集合 和 第二个操作数中的元素
  • minus 的结果包含原始集合中的元素,但第二个操作数中的元素 除外
fun main() {

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

    val plusList = numbers + "five"
    val plusList2 = plusList.plus("six")
    // [one, two, three, four, five, six]
    println(plusList2)
    
    
    val minusList = numbers - listOf("three", "four")
    // [one, two]
    println(minusList)
}
分组

Kotlin 标准库提供用于对集合元素进行分组的扩展函数。 基本函数 [groupBy()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/group-by.html) 使用一个 lambda 函数并返回一个 Map。 在此 Map 中,每个键都是 lambda 结果,而对应的值是返回此结果的元素 List

还可以使用第二个 lambda 参数(值转换函数)调用 groupBy()。 在带有两个 lambda 的 groupBy() 结果 Map 中,由 keySelector 函数生成的键映射到值转换函数的结果,而不是原始元素

groupBy
fun main() {
    val numbers = listOf("one", "two", "three", "four", "five")

    // {O=[one], T=[two, three], F=[four, five]}
    println(numbers.groupBy { it.first().uppercase() })
    // {o=[ONE], t=[TWO, THREE], f=[FOUR, FIVE]}
    println(numbers.groupBy(keySelector = { it.first() }, valueTransform = { it.uppercase() }))
}
eachCount

分组后计算每个组中的元素

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five", "six")
    // {o=1, t=2, f=2, s=1}
    println(numbers.groupingBy { it.first() }.eachCount())
}
取集合的一部分
slice

[slice()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/slice.html) 返回具有给定索引的集合元素列表。 索引既可以是作为区间传入的也可以是作为整数值的集合传入的。

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five", "six")
    // [two, three, four]
    println(numbers.slice(1..3))
    // [one, three, five]
    println(numbers.slice(0..4 step 2))
    // [four, six, one]  
    println(numbers.slice(setOf(3, 5, 0))) // 第3/5/0 索引下元素
}
take

从头获取指定数量元素

takeLast

从尾获取指定数量元素

drop

从头去除给定数量元素

dropLast

从尾去除给定数量的元素

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five", "six")
    // [one, two, three]
    println(numbers.take(3))
    // [four, five, six]
    println(numbers.takeLast(3))
    // [two, three, four, five, six]
    println(numbers.drop(1))
    // [one]
    println(numbers.dropLast(5))
}
chunked

将集合分解为给定大小的块,chunked() 采用一个参数(块的大小),并返回一个 List 其中包含给定大小的 List

fun main() {
    val numbers = (0..13).toList()
    // [[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 10, 11], [12, 13]]
    println(numbers.chunked(3))
}
windoed

可以检索给定大小的集合元素中所有可能区间。 获取它们的函数称为 [windowed()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/windowed.html): 它返回一个元素区间列表,比如通过给定大小的滑动窗口查看集合,则会看到该区间。 与 chunked() 不同,windowed() 返回从_每个_集合元素开始的元素区间(窗口)。 所有窗口都作为单个 List 的元素返回。

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five")
    // [[one, two, three], [two, three, four], [three, four, five]]
    println(numbers.windowed(3))
}
取单个元素
按位置取
elementAt

为了检索特定位置的元素,有一个函数 [elementAt()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/element-at.html)。 用一个整数作为参数来调用它,你会得到给定位置的集合元素。 第一个元素的位置是 0,最后一个元素的位置是 (size - 1)

elementAt() 对于不提供索引访问或非静态已知提供索引访问的集合很有用。 在使用 List 的情况下,使用索引访问操作符 (get()[])更为习惯。

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five")
    // four
    println(numbers.elementAt(3))
    // four
    println(numbers.get(3))
    // four
    println(numbers[3])
}
elmentArOrNull

当指定位置超出集合范围,下标越时,返回null

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five")
    // null
    println(numbers.elementAtOrNull(10))
}
elementAtOrElse

当指定位置超出集合范围,下标越时,返回指定值

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five")
    // hello
    println(numbers.elementAtOrElse(10) { "hello" })
 }
按条件取
first
last

函数 [first()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/first.html)[last()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/last.html) 还可以让你在集合中搜索与给定谓词匹配的元素。 当你使用测试集合元素的谓词调用 first() 时,你会得到对其调用谓词产生 true 的第一个元素。 反过来,带有一个谓词的 last() 返回与其匹配的最后一个元素。

fun main() {
    val numbers = listOf("one", "two", "three", "four", "five", "six")
    // three
    println(numbers.first { it.length > 3 })  // 第一个长度>3的元素
    // five
    println(numbers.last { it.startsWith("f") }) // 最后一个以f开头的元素
}

如果没有元素与谓词匹配,两个函数都会抛出异常,为了避免异常,可以使用 firstOrNull() 与 laseOrNull() 如果找不到匹配的元素,它们将返回null。

  • 使用 find 代替firstOrNull
  • 使用 findLast 代替 lastOrNull
fun main() {
    val numbers = listOf(1, 2, 3, 4)
    // null
    println(numbers.find { it % 6 == 0 })
    // 4
    println(numbers.findLast { it % 2 == 0 })
}
随机取元素
random

如果需要检索集合的一个随机元素,那么请调用 [random()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/random.html) 函数。 你可以不带参数或者使用一个 [Random](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.random/-random/index.html) 对象作为随机源来调用它。

fun main() {
    val numbers = listOf(1, 2, 3, 4)
    println(numbers.random())
}
检测元素是否存在

如需检查集合中某个元素的存在,可以使用 contains() 函数。 如果存在一个集合元素等于(equals())函数参数,那么它返回 true。 你可以使用 in 关键字以操作符的形式调用 contains()。 如需一次检查多个实例的存在,可以使用这些实例的集合作为参数调用 containsAll()。

contains
fun main() {

    val numbers = listOf("one", "two", "three", "four", "five", "six")
    // true
    println(numbers.contains("four"))
    
 }
排序
自然排序
  • sorted 升序
  • sortedDescending 降序
fun main() {

    val numbers = listOf(1, 80, 30, 3)

    // Sorted ascending: [1, 3, 30, 80]
    println("Sorted ascending: ${numbers.sorted()}")
    // Sorted descending: [80, 30, 3, 1]
    println("Sorted descending: ${numbers.sortedDescending()}")

}
自定义排序
  • sortedBy
  • _sortedByDescending _
fun main() {
    val numbers = listOf("one", "two", "three", "four")

    val sortedNumbers = numbers.sortedBy { it.length }
    // Sorted by length ascending: [one, two, four, three]
    println("Sorted by length ascending: $sortedNumbers")
    
    
    val sortedByLast = numbers.sortedByDescending { it.last() }
    // Sorted by the last letter descending: [four, two, one, three]
    println("Sorted by the last letter descending: $sortedByLast")
}
反转

可以使用 [reversed()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reversed.html)

fun main() {
    val numbers = listOf("one", "two", "three", "four")
    // [four, three, two, one]
    println(numbers.reversed())
}
随机排序

[shuffled()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/shuffled.html) 函数返回一个包含了以随机顺序排序的集合元素的新的 List

fun main() {
    val numbers = listOf("one", "two", "three", "four")
    println(numbers.shuffled())
}
聚合操作

Kotlin 集合包含用于常用的 聚合操作 (基于集合内容返回单个值的操作)的函数

  • [minOrNull()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/min-or-null.html)[maxOrNull()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/max-or-null.html) 分别返回最小和最大的元素。
  • [average()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/average.html) 返回数字集合中元素的平均值。
  • [sum()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sum.html) 返回数字集合中元素的总和。
  • [count()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/count.html) 返回集合中元素的数量。
fun main() {
    val numbers = listOf(6, 42, 10, 4)

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


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

对于更特定的情况,有函数 [reduce()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reduce.html)[fold()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/fold.html),它们依次将所提供的操作应用于集合元素并返回累积的结果。 操作有两个参数:先前的累积值和集合元素。

这两个函数的区别在于:fold() 接受一个初始值并将其用作第一步的累积值,而 reduce() 的第一步则将第一个和第二个元素作为第一步的操作参数。

fun main() {
    val numbers = listOf(5, 2, 10, 4)

    // 5 + 2*2 = 9  9 +10*2= 29   29 + 4*2 = 37
    val sumDoubledReduce = numbers.reduce { sum, element -> sum + element * 2 }
    println(sumDoubledReduce)
    
    val sumDoubled = numbers.fold(0) { sum, element -> sum + element * 2 }
    println(sumDoubled)
}
List 相关操作
按索引取元素
  • get
  • first
  • last
  • getOrElse : 提供用于计算默认值的函数,如果集合中不存在索引,则返回默认值。
  • getOrNull : 返回 null 作为默认值。
取列表的一部分 subList
fun main() {
    val numbers = (0..13).toList()
    // [3, 4, 5]
    println(numbers.subList(3, 6))
}
查找元素位置
  • indexOf
  • lastIndexOf
  • indexOfFirst() : 返回与谓词匹配的_第一个元素的索引_,如果没有此类元素,则返回 -1
  • indexOfLast() : 返回与谓词匹配的_最后一个元素的索引_,如果没有此类元素,则返回 -1
fun main() {
    val numbers = mutableListOf(1, 2, 3, 4)
    // 2 下标
    println(numbers.indexOfFirst { it > 2})
    // 2 下标
    println(numbers.indexOfLast { it % 2 == 1})
}
添加
  • add
  • addAll
fun main(){
    val numbers = mutableListOf("one", "five", "six")
    numbers.add(1, "two")
    numbers.addAll(2, listOf("three", "four"))
    println(numbers)
}
更新
  • set
  • 操作符形式 []
fun main() {
    val numbers = mutableListOf("one", "five", "three")
    numbers[1] =  "two"
    println(numbers)
}
  • fill() 将集合中元素的值全部替换为指定值
fun main() {
    val numbers = mutableListOf(1, 2, 3, 4)
    numbers.fill(3)
    // [3, 3, 3, 3]
    println(numbers)
}
删除
  • removeAt
fun main() {
    val numbers = mutableListOf(1, 2, 3, 4, 3)
    numbers.removeAt(1)
    // [1, 3, 4, 3]
    println(numbers)
}
排序

在集合排序中,描述了按特定顺序检索集合元素的操作。 对于可变列表,标准库中提供了类似的扩展函数,这些扩展函数可以执行相同的排序操作。 将此类操作应用于列表实例时,它将更改指定实例中元素的顺序。

就地排序函数的名称与应用于只读列表的函数的名称相似,但没有 ed/d 后缀:

  • sort* 在所有排序函数的名称中代替 sorted*[sort()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort.html)[sortDescending()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort-descending.html)[sortBy()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/sort-by.html) 等等。
  • [shuffle()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/shuffle.html) 代替 shuffled()
  • [reverse()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/reverse.html) 代替 reversed()

[asReversed()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/as-reversed.html) 在可变列表上调用会返回另一个可变列表,该列表是原始列表的反向视图。在该视图中的更改将反映在原始列表中。 以下示例展示了可变列表的排序函数:

fun main() {
    val numbers = mutableListOf(1, 30, 8, 55)

    numbers.sort()
    // [1, 8, 30, 55]
    println("按升序排序: $numbers")
    numbers.sortDescending()
    // [55, 30, 8, 1]
    println("按降序排序: $numbers")

    numbers.sortBy { it % 2 }
    // [30, 8, 55, 1]
    println("it % 2 sorted: $numbers")
    numbers.sortByDescending { it }
    // [55, 30, 8, 1]
    println("it % 2 sortByDescending : $numbers")

    numbers.sortWith(compareBy<Int> { it }.thenBy { it })
    // [1, 8, 30, 55]
    println("Sort by Comparator: $numbers")

    numbers.shuffle()
    // [1, 30, 55, 8]
    println("Shuffle: $numbers")

    numbers.reverse()
    //  [8, 55, 30, 1]
    println("Reverse: $numbers")
}
Set 相关操作

Kotlin 集合包中包含 set 常用操作的扩展函数: 找出集合间的交集、并集或差集。

并集

union函数,也能使用中缀形式使用 a union b.

fun main() {
    val numbers = setOf("one", "two", "three")
    // [one, two, three, four, five]
    println(numbers union setOf("four", "five"))
     // [four, five, one, two, three]
    println(setOf("four", "five") union numbers) 
}
交集

要找到两个集合(两个集合中都有的元素)的交集,请使用 intersect() 函数

fun main() {
    val numbers = setOf("one", "two", "three")
    // [one, two]
    println(numbers intersect setOf("two", "one"))
 }
差集

要找到不在另一个集合中的集合元素,请使用 subtract() 函数

fun main() {
    val numbers = setOf("one", "two", "three")
    // [one, two]
    println(numbers subtract setOf("three", "four"))
    // [one, two]
    println(numbers - setOf("three", "four"))
}

计算两个集合之间的差异,并将结果合并:

fun main() {

    val numbers = setOf("one", "two", "three")
    val numbers2 = setOf("three", "four")

     // [one, two, four]
    println((numbers - numbers2) union (numbers2 - numbers))
}
Map 相关操作
取值
  • get()
  • [key]
  • getValue()
  • getOrElse()
  • getOrDefault()
fun main() {

    val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    println(numbersMap.get("one"))
    println(numbersMap["one"]) 
    println(numbersMap.getOrDefault("four", 10))
    println(numbersMap["five"])    // null
    //numbersMap.getValue("six")      // exception!
}

要对 map 的所有键或所有值执行操作,可以从属性 keysvalues 中相应地检索它们。 keys 是 Map 中所有键的集合, values 是 Map 中所有值的集合。

fun main() {
    val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    // [one, two, three]
    println(numbersMap.keys)
    // [1, 2, 3]
    println(numbersMap.values)
}
过滤

可以使用 [filter()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter.html) 函数来过滤 map 或其他集合。 对 map 使用 filter() 函数时, Pair 将作为参数的谓词传递给它。 它将使用谓词同时过滤其中的键和值。

fun main() {
    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}
    // {key11=11}
    println(filteredMap)
}

还有两种用于过滤 map 的特定函数:按键或按值。 这两种方式,都有对应的函数: [filterKeys()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter-keys.html)[filterValues()](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/filter-values.html) 。 两者都将返回一个新 Map ,其中包含与给定谓词相匹配的条目。 filterKeys() 的谓词仅检查元素键, filterValues() 的谓词仅检查值。

fun main() {
    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 }

    // {key1=1, key11=11}
    println(filteredKeysMap)
    
    //{key1=1, key2=2, key3=3} 
    println(filteredValuesMap)
}
加减操作符

由于需要访问元素的键,[plus](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/plus.html)+)与 [minus](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/minus.html)-)运算符对 map 的作用与其他集合不同。 plus 返回包含两个操作数元素的 Map :左侧的 Map 与右侧的 Pair 或另一个 Map 。 当右侧操作数中有左侧 Map 中已存在的键时, 该条目将使用右侧的值。

fun main() {
    val numbersMap = mapOf("one" to 1, "two" to 2, "three" to 3)
    // {one=1, two=2, three=3, four=4}
    println(numbersMap + Pair("four", 4))
    // {one=10, two=2, three=3}
    println(numbersMap + Pair("one", 10))
    // {one=11, two=2, three=3, five=5}
    println(numbersMap + mapOf("five" to 5, "one" to 11))
}
写操作
  • put
  • putAll

其参数可以是Map或一组Pair

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
    numbersMap.putAll(setOf("four" to 4, "five" to 5))
    // {one=1, two=2, three=3, four=4, five=5}
    println(numbersMap)
}
删除条目
  • Remove 如果同时指定键和值,则仅当键值都匹配时,才会删除此的元素。
fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
    numbersMap.remove("one")
    // {two=2, three=3}
    println(numbersMap)
    numbersMap.remove("three", 4)            //不会删除任何条目
    // {two=2, three=3}
    println(numbersMap)
}

使用 -= 操作也可以用于可变map

fun main() {
    val numbersMap = mutableMapOf("one" to 1, "two" to 2, "three" to 3)
    // {one=1, three=3}
    numbersMap -= "two"
    println(numbersMap)
    numbersMap -= "five"             //不会删除任何条目
    // {one=1, three=3}
    println(numbersMap)
}

作用域函数

Kotlin 提供一组强大的作用域函数,用于简化对象的操作和管理,这些函数包括 let 、run 、with、apply和also。它们的主要区别在于上下文对象的引用方式和返回值不同

上下文对象

  • this

run、with、以及apply通过关键字将上下文对象引用为lambda表达式的接受者。因此,在它们的lambda表达式中可以像在普通的类函数一样访问上下文对象。

data class Person(var name: String, var age: Int = 0, var city: String = "")

val adam = Person("Adam").apply { 
        age = 20                       // 同 this.age = 20
        city = "London"
    }
  • it

像let 及 also将上下文对象引用为lambda表达式参数,如果没有指定参数名,对象可以用隐式默认名称it访问。

fun getRandomInt(): Int {
        return Random.nextInt(100).also {
            println("value $it")
        }
}

返回值

根据返回结果,作用域函数可以分为以下两类

  • apply、also 返回上下文对象
  • let 、run 、 with 返回lambda表达式的结果

let

用途: 适用于对非空对象执行某些操作,或者在链式调用中转换结果

上下文对象:it

返回值:lambda表达式的结果

使用场景:

  • 链式调用中处理非空结果
  • 执行某些操作并返回一个新的结果
val str = "Hello, World!"
val length = str.let {
    println(it) // 输出: Hello, World!
    it.length
}
println(length) // 输出: 13

run

用途:用于初始化或配置对象,或者执行一系列操作并返回计算结果

上下文:使用this引用

返回值:lambda表达式的结果

使用场景:

  • 初始化或配置复杂对象
  • 执行多步计算并返回最终结果
val result = "Hello".run {
    println(this) // 输出: Hello
    length
}
println(result) // 输出: 5

with

用途:用于对同一个对象执行多次操作,通常用于对象的配置

上下文:使用this引用

返回值:lambda表达式的结果

使用场景:

  • 对单个对象执行多个操作
  • 配置复杂对象时提高代码可读性
val builder = StringBuilder()
val result = with(builder) {
    append("Hello, ")
    append("World!")
    toString()
}
println(result) // 输出: Hello, World!

apply

用途:用于配置对象属性,常用构建器模式

上下文:使用this引用

返回值: 上下文对象本身

使用场景:

  • 初始化或设置对象属性时保持流畅的 API 调用风格
  • 配置新创建的实例
val person = Person().apply {
    name = "John"
    age = 30
}
println(person) // 输出: Person(name=John, age=30)

also

用途:用于在链式调用中执行额外操作,不修改原始数据

上下文:使用it引用

返回值: 上下文对象本身

使用场景:

  • 在不改变原始数据结构的情况下记录日志或调试信息。
  • 在链式调用中添加副作用操作(例如打印日志)
val numbers = mutableListOf("one", "two", "three")
numbers.also { println("Original list: $it") }
       .add("four")
      
println(numbers) 
 // Original list: [one, two, three]       
 // [one, two, three, four]

takeIf / takeUnless

用于条件判断的扩展函数,它们可以帮助你根据条件选择性地返回对象本身或null,从而简化代码中条件逻辑。

  • takeIf

用途:当对象满足给定的条件时,返回该对象,否则返回null

val number = 10

val result = number.takeIf { it > 5 }
println(result) // 输出: 10,因为条件 it > 5 为 true

val nullResult = number.takeIf { it < 5 }
println(nullResult) // 输出: null,因为条件 it < 5 为 false
  • takeUnless

用途:当对象不满足给定条件时,返回该对象,否则返回null

val number = 10

val result = number.takeUnless { it < 5 }
println(result) // 输出: 10,因为条件 it < 5 为 false

val nullResult = number.takeUnless { it > 5 }
println(nullResult) // 输出: null,因为条件 it > 5 为 true

时间度量

kotlin的Duration类是用于表示时间间隔的一个强大工具,它提供了多种方法来创建,操作和格式化时间间隔。

创建时间

import kotlin.time.*
import kotlin.time.Duration.Companion.nanoseconds
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.Duration.Companion.seconds
import kotlin.time.Duration.Companion.minutes
import kotlin.time.Duration.Companion.days
fun main() {

    val fiveHundredMilliseconds: Duration = 500.milliseconds
    val zeroSeconds: Duration = 0.seconds
    val tenMinutes: Duration = 10.minutes
    
    
    println(fiveHundredMilliseconds) // 500ms
    println(zeroSeconds)             // 0s
    println(tenMinutes)              // 10m
    
    }

也可以使用Duration对象执行基本的算术运算

import kotlin.time.*
import kotlin.time.Duration.Companion.seconds

fun main() {

    val fiveSeconds: Duration = 5.seconds
    val thirtySeconds: Duration = 30.seconds
    
    println(fiveSeconds + thirtySeconds)// 35s
    println(thirtySeconds - fiveSeconds)// 25s
    println(fiveSeconds * 2)// 10s
    println(thirtySeconds / 2) // 15s
    println(thirtySeconds / fiveSeconds)// 6.0
    println(-thirtySeconds)// -30s
    println((-thirtySeconds).absoluteValue)// 30s
}

获取字符串表现形式

import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import kotlin.time.DurationUnit

fun main() {
    println(5887.milliseconds.toString(DurationUnit.SECONDS, 2))
    // 5.89s
}

转换持久时间

要将您的 转换Duration为不同的DurationUnit,请使用以下属性:

  • inWholeNanoseconds
  • inWholeMicroseconds
  • inWholeSeconds
  • inWholeMinutes
  • inWholeHours
  • inWholeDays
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
fun main() {
    val thirtyMinutes: Duration = 30.minutes
    println(thirtyMinutes.inWholeSeconds)// 1800
}

DurationUnit或者,您可以在以下扩展函数中使用您想要的作为函数参数:

  • .toInt()
  • .toDouble()
  • .toLong()
import kotlin.time.Duration.Companion.seconds
import kotlin.time.DurationUnit
fun main() {
    println(270.seconds.toDouble(DurationUnit.MINUTES))
    // 4.5
}

比较持续时间

使用运算符: == 、< 、>

import kotlin.time.Duration
import kotlin.time.Duration.Companion.hours
import kotlin.time.Duration.Companion.minutes
fun main() {
    val thirtyMinutes: Duration = 30.minutes
    val halfHour: Duration = 0.5.hours
    println(thirtyMinutes == halfHour)// true
    
    
    println(3000.microseconds < 25000.nanoseconds) // false
}

http://www.kler.cn/a/455647.html

相关文章:

  • 六十:HTTP/2与gRPC框架
  • Android 13 Launcher3 移除桌面抽屉入口
  • 0039__屏幕帧缓冲机制
  • 五模型对比!Transformer-GRU、Transformer、CNN-GRU、GRU、CNN五模型多变量时间序列预测
  • 【MySQL】01.MySQL环境安装
  • 【多维DP】力扣3366. 最小数组和
  • [2029].第6-06节:MyISAM引擎中的索引与 InnoDB引擎中的索引对比
  • C# 线程安全集合
  • 阿里云技术公开课:基于阿里云 Elasticsearch 构建 AI 搜索和可观测 Chatbot
  • 计算机故障找不到x3daudio1_7.dll怎么解决?
  • C#开发实例2—模拟考试
  • Jsonlizer,一个把C++各类数据转成 Json 结构体的玩意儿
  • asp.net core系统记录当前在线人数
  • 组建基于IPV6的网络
  • 更新本地项目到最新git版本脚本
  • 每天40分玩转Django:Django Email
  • 微服务网关路由
  • node.js高级用法
  • LeetCode -Hot100 - 56. 合并区间
  • 【centos8 镜像修改】centos8 镜像修改阿里云
  • c++编译过程初识
  • 【Java 代码审计入门-03】XSS 漏洞原理与实际案例介绍
  • MFC扩展库BCGControlBar Pro v36.0 - 可视化管理器等全新升级
  • Vision Transformer (ViT) 论文的第二句话
  • 踏踏实实练SQLday2-3连续12345
  • 机器学习2-NumPy