Kotlin学习笔记之集合

本文详细介绍了Kotlin中的集合类型,包括List、Set、Map的特性与区别。讲解了集合的构造、迭代器的使用,以及如何进行集合转换、过滤、取集合部分、排序和聚合操作。此外,还探讨了List的索引访问、查找操作和二分查找,以及Set和Map的相关操作。通过对Kotlin集合的深入学习,有助于更好地理解和应用这些数据结构。
摘要由CSDN通过智能技术生成

1.集合概述

kotlin集合主要有三类

  • List 是一个有序集合,可通过索引(反映元素位置的整数)访问元素。
  • Set 集合中的元素是唯一的,不可重复。
  • Map(或者字典)是一组键值对。

1.1 集合类型

集合结构可以用以下两种归纳来区分:

  • 一个 只读 接口,提供访问集合元素的操作。

  • 一个 可变 (可读可写)接口,通过写操作扩展相应的只读接口:添加、删除和更新其元素。

而集合的只读并不是通过val来修饰,也就是说并不能使得该集合只读。他只是保障了该集合的引用是不可变的,如下所示:

val numbers = mutableListOf("one", "two", "three", "four")
fun main() {
   
    numbers.add("five")//
    println(numbers)
    numbers = mutableListOf("one", "two", "three", "four")//error: val cannot be reassigned
}

kotlin集合接口如下所示:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mNRnCyyb-1596274969133)(http://www.kotlincn.net/assets/images/reference/collections-overview/collections-diagram.png)]

1.2 Collection

可以看到Collection实现了Iterable接口,它定义了迭代操作的实现。同时Collection定义了集合的公共行为,比如说检索大小等。

fun printAll(strings: Collection<String>) {
   
    for(s in strings) print("$s ")
    println()
}


fun main() {
   
    val stringList = listOf("one", "two", "one")
    printAll(stringList)
    
    val stringSet = setOf("one", "two", "three")
    printAll(stringSet)
}

MutableCollections在Collection的基础上增加了add以及remove等修改操作。

1.3 List

List顺序存储元素,并且可以通过索引取值。这点容易理解,比较值得注意的是两个List之间的对比。如果两个列表对应的值一样,那么我们就可以认定其相等的:

data class Person(var name:String,var age:Int)

fun main() {
   
    val bob = Person("Bob", 31)
    val people = listOf<Person>(Person("Adam", 20), bob, bob)
    val people2 = listOf<Person>(Person("Adam", 20), Person("Bob", 31), bob)
    println(people == people2)
    bob.age = 32
    println(people == people2)
}

1.4 Set

首先set是无顺序的,null也可以时Set的元素。当两个Set的元素可以一一对应且相等的时候,那么就可以判断两个set是相等的.

Set还有两个实现LinkHashSet以及HashSet.LinkHashSet是Set的默认实现,保留了顺序的特性也提供了依赖于顺序的函数.而HashSet不依赖于顺序,当时其所需的内存更少

1.5 Map

Map的用法和java差不多.重点是如何判断两个Map是相等的:

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

println("The maps are equal: ${
     numbersMap == anotherMap}")//无论键值对的顺序如何,包含相同键值对的两个 Map 是相等的

和Set差不多,加个Mutable就转变为了可修改的集合.默认的实现是LinkHashMap,他是有顺序的.而另一个实现是HashMap,他是不带顺序的.

2. 构造集合

2.1 集合的初始化

首先说说只读集合的情况,List和Set可以用List()以及Set().Map的话有mapOf(),而键值对可以通过以下的方式赋值:

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

这种写法直观明了,但是它会创建一个临时的Pair对象,因此还是比较耗性能的。可以用其他方式来赋值:

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

只读集合的空集合,他可以用三个方式表示:emptyList()emptySet()emptyMap()。其中创建空集合时,应指定集合所包含的的元素类型。

接下来说说可变集合的表示方法,他么比不可变集合多了个mutable,其他差不多:mutableMapOf()mutableListOf<T>()mutableSetOf<T>()

2.2 List的初始化函数

List可以用函数来初始化。List后面跟着一个小括号,左边是该List 的大小,右边是构造函数。

val doubled = List(3, {
    it * 2 })  // 不可边集合,it代表的是索引号
val mutableDoubled = MutableList(3, {
    it * 2 })  // 可变集合
println(doubled)

2.3 各个具体类型的创建

具体类型的集合可以用过List这种基本类型装饰而成:

val linkedList = LinkedList<String>(listOf("one", "two", "three"))

2.4 集合的复制

首先是浅拷贝,也就是创建特定存在集合的新引用:

val sourceList = mutableListOf(1, 2, 3)
val referenceList = sourceList
referenceList.add(4)//referenceList改变的同时,sourceList也发生了变化

同时初始化的时候也可以改变其可变性:

val sourceList = mutableListOf(1, 2, 3)
val referenceList: List<Int> = sourceList

接下来是深拷贝,通过集合复制函数来创建独立的副本,例如toList()toMutableList()toSet()

val sourceList = mutableListOf(1, 2, 3)
val copyList = sourceList.toMutableList()
val readOnlyCopyList = sourceList.toList()

这些函数还可用于将集合转换为其他类型,例如根据 List 构建 Set,反之亦然。

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

2.5 调用其他集合的函数

可以通过其他集合的各种操作来生成新的集合,比如说过滤。

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

新的集合也可以通过其他集合的映射得出:

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

Map可以通过集合的关联来生成:

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

3. 迭代器

3.1 基本用法

主要有三种遍历方式:1.Iterable集合的方式,该方式遍历到集合尾部的时候就不能再用了。2.for循环的方式.3.foreach的方式。

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

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

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

3.2 双向迭代器

双向迭代的能力意味着可以向后迭代也可以向前迭代,即便是迭代道最后一个元素也可以继续使用:

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()}")
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值