Kotlin学习 - 集合

List集合

Kotlin集合分为可变集合和不可变集合,不可变的集合指的就是该集合只能用于读取,无法进行添加、修改或删除操作。

1、不可变集合

val fruits = listOf<String>("apple","orange","pear")

2、可变集合

fun main() {
    
    
    val names = mutableListOf("Tom", "Lucky", "Daniel")
    names.add("Alice")
    names+= "Sara"
    
	for (name in names){
    
    
		print("$name - ")
	}
}

3、集合类型转换

不可变集合转可变集合toMutableList()

fun main() {
    
    
	val fruits = listOf("apple", "orange", "pear")
	val newFruits = fruits.toMutableList()
    newFruits.add("kiwi")
    println(fruits)
    println(newFruits)
}
//运行结果:
[apple, orange, pear]
[apple, orange, pear, kiwi]

可变集合转不可变集合:toList()

fun main() {
    
    
    val names = mutableListOf("Tom", "Lucky", "Daniel")
    val newNames = names.toList()
    names.add("Alice")
    println(names)
    println(newNames)
}
//运行结果:
[Tom, Lucky, Daniel, Alice]
[Tom, Lucky, Daniel]

注意调用转换集合类型函数会生成一个新的集合对象,原来的类型不受影响。

4、集合元素读取

fun main() {
    
    
    val fruits = listOf("apple", "orange", "pear")
    println(fruits.get(2))//Should be replaced with indexing
    println(fruits[2])
}

元素读取有两种方式,一种是和Java一样使用get,但是Kotlin编译器会提示:Should be replaced with indexing,提倡使用像Java中数组一样加中括号和索引读取元素。

fun main() {
    
    
    val fruits = listOf("apple", "orange", "pear")
    println(fruits[5])
}

在使用索引读取元素的时候,很容易出现数组越界的风险,例如上面代码报错:越界ArrayIndexOutOfBoundsException。

解决越界,可以使用安全索引取值方法: getOrElse或者getOrNullgetOrElse传入索引和出错后返回的Lambda表达式,getOrNull传入索引,找不到返回是null

fun main() {
    
    
    val fruits = listOf("apple", "orange", "pear")
    println(fruits.getOrElse(4) {
    
    
        "IndexOutOfBounds"
    })
    
    println(fruits.getOrNull(4))
    println(fruits.getOrNull(4) ?: "IndexOutOfBounds")
}

5、集合元素遍历

fun main() {
    
    
	val names = mutableListOf("Tom", "Lucky", "Daniel")
	for (name in names){
    
    
		print("$name - ")
	}
	
	println()
	names.forEach{
    
    
		print("$it * ")
	}
	
	println()
	//遍历同时获取索引
	names.forEachIndexed{
    
     index,item ->
		print("$index-$item & ")
	}
}

运行结果:
Tom - Lucky - Daniel - 
Tom * Lucky * Daniel * 
0-Tom & 1-Lucky & 2-Daniel & 

Map集合

1、不可变集合

val fruits = mapOf("apple" to 2.5, "orange" to 5, "pear" to 3)

这里key值和value是通过to进行连接,但是to并不是关键字,而是一个infix函数。

2、可变集合

fun main() {
    
    
	//初始化方式一
    var fruits = mutableMapOf("apple" to 2.5, "orange" to 5, "pear" to 3)
    //初始化方式二
    var fruitList = mutableMapOf(Pair("apple",2.5) ,Pair("orange",5),Pair("pear",3))
    //添加元素
    fruits.put("kiwi",6)//不推荐
    fruits["banana"] = 5//推荐
    fruits += "watermelon" to 10
    
    for ((key, value) in fruits){
    
    
        println("$key's price is $value")
    }
}

3、集合类型转换

fun main() {
    
    
    val fruits = mapOf("apple" to 2.5, "orange" to 5, "pear" to 3)
    val newFruits = fruits.toMutableMap()
    newFruits.put("kiwi",6)   
    println(newFruits)

    var fruits = mutableMapOf("apple" to 2.5, "orange" to 5, "pear" to 3)
    println(fruits.toMap())
}

4、集合元素读取

fun main() {
    
    
    val fruits = mapOf("apple" to 2.5, "orange" to 5, "pear" to 3)
    println(fruits["apple"])
    println(fruits.getValue("apple"))
    println(fruits.getOrElse("banana") {
    
     "banana has not price" })
    println(fruits.getOrDefault("banana", 0))
}
//运行结果
2.5
2.5
banana has not price
0

5、集合元素遍历

fun main() {
    
    
	val fruits = mapOf("apple" to 2.5, "orange" to 5, "pear" to 3)
	fruits.forEach {
    
    
		println("${
      
      it.key} + ${
      
      it.value}  ")
	}
}
//运行结果:
apple + 2.5  
orange + 5  
pear + 3  

Set集合

1、不可变集合

val set = setOf("apple", "orange", "pear", "pear")

2、可变集合

val mutableSet = mutableSetOf("apple", "orange", "pear", "pear")

3、集合类型转换

fun main() {
    
    
    val set = setOf("apple", "orange", "pear", "pear")
    val newSet = set.toMutableSet();
    newSet.add("banana")
    newSet += "kiwi"
    //添加元素
    println(newSet)
    
    val mutableSet = mutableSetOf("apple", "orange", "pear", "pear")
    println(mutableSet.toSet())
}

4、集合元素读取

fun main() {
    
    
	val set = setOf("apple", "orange", "pear", "pear")
	println(set.elementAt(1))
}

//运行结果:orange

5、集合元素遍历

fun main() {
    
    
	val set = setOf("apple", "orange", "pear", "pear")
	set.forEach{
    
    
        print("$it ")
    }
}
//运行结果
apple orange pear 

注意:Set和List相比有个特点就是集合数据均不相同,都是唯一的,所以上面例子打印出来只有一个"pear"

List去重的两种方式:

fun main() {
    
    
    val list = listOf("apple", "orange", "pear", "pear")
    //去重方式1
    val newList = list.toSet().toList()
    println(list)
    println(newList)
    //去重方式2 快捷函数distinct
    val newList1 = list.distinct()
    println(list)
    println(newList1)
}
//运行结果
[apple, orange, pear, pear]
[apple, orange, pear]
[apple, orange, pear, pear]
[apple, orange, pear]

上面在添加元素的时候有的用了运算符,看不懂的小伙伴可以去看下另一篇文章Kotlin学习 - 运算符重载

集合的函数式API

API - maxByOrNull

这里有个需求找到上面列表中水果名字最长的水果:

fun main() {
    
    
	val fruits = listOf<String>("apple", "orange", "pear", "watermelon")
	val maxLengthFruit = fruits.maxByOrNull {
    
     it.length }
	println(maxLengthFruit)
}
//运行结果:watermelon

这里用到的maxByOrNull 就是集合的函数式API,作用是根据大括号中Lambda表达式筛选出符合条件最大的。

1、Lambda表达式使用

Lambda语法结构:

{参数名1: 参数类型, 参数名2: 参数类型 -> 函数体}

maxByOrNull函数需要一个Lambda表达式,最初的写法如下:

val lambda = {
    
     fruit: String -> fruit.length }
val maxLengthFruit = fruits.maxByOrNull(lambda )

2、Lambda表达式简化写法

在很多情况下,我们并不需要使用Lambda 表达式完整的语法结构,而是有很多种简化的写法。

1)直接把Lambda表达式传入到函数中,不在单独声明:

val maxLengthFruit = fruits.maxByOrNull({
    
     fruit: String -> fruit.length })

2)当Lambda 参数是函数的最后一个参数时,可以将Lambda 表达式移到函数括号的外面:

val maxLengthFruit = fruits.maxByOrNull(){
    
     fruit: String -> fruit.length }

3)如果Lambda 参数是函数的唯一一个参数的话,还可以将函数的括号省略

val maxLengthFruit = fruits.maxByOrNull{
    
     fruit: String -> fruit.length }

4)因为Kotlin拥有出色的类型推导机制,所以入参类型可以去掉:

val maxLengthFruit = fruits.maxByOrNull{
    
     fruit -> fruit.length }

5)当Lambda 表达式的参数列表中只有一个参数时,也不必声明参数名,而是可以使用it关键字来代替:

val maxLengthFruit = fruits.maxByOrNull {
    
     it.length }

经过上面一系列的变化最后得到了刚开始写的语句。

3、练习:模仿上面例子可以写一个筛选出水果中价格最大的水果:

fun main() {
    
    
	var fruitsMap = mutableMapOf("apple" to 2.5, "orange" to 5, "pear" to 3)
	val maxPriceFruit = fruitsMap.maxByOrNull {
    
     it.value.toFloat() }
	println(maxPriceFruit?.key)
}
//运行结果:orange

API - map

API map将集合中的每个元素都映射成一个另外的值,映射的规则在Lambda 表达式中指定,最终生成一个新的集合。

fun main() {
    
    
	val fruits = listOf<String>("apple", "orange", "pear", "watermelon")
	val newFruitList = fruits.map {
    
     it.uppercase() }
	println(newFruitList)
}

//[APPLE, ORANGE, PEAR, WATERMELON]

API - filter

filter函数是用来过滤集合中的数据的,它可以单独使用,也可以配合map函数一起使用。

需求:将水果名字长度大于5的水果转为大写

fun main() {
    
    
	val fruits = listOf<String>("apple", "orange", "pear", "watermelon")
	val newFruitList = fruits.filter {
    
     it.length > 5 }.map {
    
     it.uppercase() }
	println(newFruitList)
}

//[ORANGE, WATERMELON]

API - anyall

any函数用于判断集合中是否至少存在一个元素满足指定条件,all函数用于判断集合中是否所有元素都满足指定条件。

fun main() {
    
    
	val fruits = listOf<String>("apple", "orange", "pear", "watermelon")
	val anyResult = fruits.any {
    
     it.length > 5 }
    val allResult = fruits.all {
    
     it.length > 5 }
    println("anyResult: $anyResult | allResult: $allResult")
}

//anyResult: true | allResult: false

本文参考书籍:《第一行代码》- 郭霖

猜你喜欢

转载自blog.csdn.net/kongqwesd12/article/details/131232666