Kotlin集合类

集合类概述

Kotlin复用了Java集合类,并且在Java类库的基础上进行了改造和扩展,没有重复造轮子。
Kotlin引入了不可变集合类,同时扩展了大量实用的功能,API在kotlin.collections包下。
Kotlin集合类不仅可以持有普通对象,还能持有函数类型的对象 —— 面向对象范式混合了函数式编程。

// 例如:
fun testFunCollection(): Unit {
    // 声明一个持有类型为函数 (Int)->Boolean 的集合
    // (Int)->Boolean 代表输入为Int类型,输出为Boolean类型的函数
    val funList:List<(Int)->Boolean> = listOf(
        {it%3==1},{it%3==2},{it%3==0}
    ) // 第一个对象是函数 {it%3==1},第二个对象是函数 {it%3==2} ...

    val myData = listOf(1,2,3,4,5,6,7,8,9)
    val r0 = myData.filter(funList[0])  // 传入funList的第一个函数
    println(r0) // 输出:[1, 4, 7]
    val r1 = myData.filter(funList[1])  // 传入funList的第二个函数
    println(r1) // 输出:[2, 5, 8]
    val r2 = myData.filter(funList[2])  // 传入funList的第三个函数
    println(r2) // 输出:[3, 6, 9]
}

Kotlin集合类分为

  1. 可变集合类(Mutable)
  2. 不可变集合类(Immutable)

常用的3种集合类

  1. 列表(List)
  2. 集(Set)
  3. 映射(Map)
  • 列表(List)容器中的元素以线性方式存储,元素有序排列,集合中可以存放重复元素;
    列表分为只读不可变的List和可写入、可删除数据的MutableList。

  • 集(Set)容器中的元素无序、不重复;
    集容器分为不可变Set和可变MutableSet(可写入、可删除数据)。

  • 映射(Map)容器中持有的是“键值对”对象,关键字(Key)是唯一的、不重复的。
    映射容器也一样,分为不可变Map和可变MutableMap(可写入、可删除数据);
    Map没有继承自Collection接口。

创建集合类

  • Kotlin中分别使用 listOf(),setOf(),mapOf() 函数创建不可变的列表(List)容器、集(Set)容器和映射(Map)容器;
  • 使用 MutableListOf(),MutableSetOf(),MutableMapOf() 函数创建可变的MutableList列表容器、MutableSet集容器和MutableMap映射容器。
fun testCollectionInit(): Unit {
    val list = listOf(1,2,3,5,5,6,8,8,9)
    println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
    val mutableList = mutableListOf("a","b","c","a")
    println(mutableList) // 输出:[a, b, c, a],列表中元素是可以重复的

    val set = setOf(1,2,3,5,5,6,8,8,9)
    println(set) // 输出:[1, 2, 3, 5, 6, 8, 9],结果去除重复
    val mutableSet = mutableSetOf("a","b","c","a")
    println(mutableSet) // 输出:[a, b, c],结果去除重复

    val map = mapOf(1 to "a", 2 to "b", 3 to "a", 4 to 99, 1 to "xy")
    println(map) // 输出:{1=xy, 2=b, 3=a, 4=99},key值唯一
    val mutableMap = mutableMapOf(1 to "X", 2 to "Y", 3 to "Y", 4 to 99, 1 to "ABC")
    println(mutableMap) // 输出:{1=ABC, 2=Y, 3=Y, 4=99},key值唯一
}

遍历集合中的元素

  • forEach() 函数
    List、Set类 继承了 Iterable 接口,扩展了 forEach() 函数来遍历元素;
    Map类也扩展了 forEach() 函数来遍历元素;

  • forEachIndexed() 函数
    List、Set类中的 forEachIndexed() 函数,在遍历元素的时候访问元素的index下标.

  • Map中的 entries 属性
    Map中的元素类型是 Entry 类型,由 entries 属性持有, entries 类型是Set

    public val entries: Set<Map.Entry<K, V>>

代码示例:

fun testCollectionInit(): Unit {
    val list = listOf(1,2,3,5,5,6,8,8,9)
    println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
    val mutableList = mutableListOf("a","b","c","a")
    println(mutableList) // 输出:[a, b, c, a],列表中元素是可以重复的
    list.forEach {
        print(it)
        print(" - ")
    } // 输出:1 - 2 - 3 - 5 - 5 - 6 - 8 - 8 - 9 -

    println()
    list.forEachIndexed { index, value ->
        print("index=$index,value=$value  ")
    } // 输出:index=0,value=1  index=1,value=2  index=2,value=3 .......

    println("-------------------")
    val set = setOf(1,2,3,5,5,6,8,8,9)
    println(set) // 输出:[1, 2, 3, 5, 6, 8, 9],结果去除重复
    val mutableSet = mutableSetOf("a","b","c","a")
    println(mutableSet) // 输出:[a, b, c],结果去除重复
    set.forEach {
        print(it)
        print(" - ")
    } // 输出:1 - 2 - 3 - 5 - 6 - 8 - 9 -

    println()
    set.forEachIndexed { index, value ->
        print("index=$index,value=$value  ")
    } // 输出:index=0,value=1  index=1,value=2  index=2,value=3 .......

    println("-------------------")
    val map = mapOf(1 to "a", 2 to "b", 3 to "a", 4 to 99, 1 to "xy")
    println(map) // 输出:{1=xy, 2=b, 3=a, 4=99},key值唯一
    val mutableMap = mutableMapOf(1 to "X", 2 to "Y", 3 to "Y", 4 to 99, 1 to "ABC")
    println(mutableMap) // 输出:{1=ABC, 2=Y, 3=Y, 4=99},key值唯一
    map.forEach {
        print("key=${it.key},value=${it.value}  ")
    } // 输出:key=1,value=xy  key=2,value=b  key=3,value=a  key=4,value=99
    println()

    val me = map.entries
    println(me) // 输出:[1=xy, 2=b, 3=a, 4=99]
    me.forEachIndexed { index, entry ->
        print("index=$index,key=${entry.key},value=${entry.value}  ")
    } // 输出:index=0,key=1,value=xy  index=1,key=2,value=b ......
}

集合类的映射函数

集合类的map()函数,可以将集合中的元素依次使用输入的函数进行映射操作
元素映射之后的新值回保存到一个新的集合对象中,并且返回这个新集合对象。

fun testFunMap(): Unit {
    val list = listOf(1,2,3,5,5,6,8,8,9)
    val set = setOf(1,2,3,5,5,6,8,8,9)
    val map = mapOf(1 to "a", 2 to "b", 3 to "xy")

    val l2 = list.map { it*2 } // 函数对每个元素进行乘以2操作
    println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
    println(l2) // 输出:[2, 4, 6, 10, 10, 12, 16, 16, 18]

    val s2 = set.map { it + 10 } // 函数对每个元素进行 加10操作
    println(set) // 输出:[1, 2, 3, 5, 6, 8, 9]
    println(s2) // 输出:[11, 12, 13, 15, 16, 18, 19]

    val m2 = map.map {  it.value + "_ok" }
    println(map) // 输出:{1=a, 2=b, 3=xy}
    println(m2) // 输出:[a_ok, b_ok, xy_ok]
}

集合类的map()函数定义:

public inline fun <T, R> Iterable<T>.map(transform: (T) -> R): List<R> {
    return mapTo(ArrayList<R>(collectionSizeOrDefault(10)), transform)
}

public inline fun <K, V, R> Map<out K, V>.map(transform: (Map.Entry<K, V>) -> R): List<R> {
    return mapTo(ArrayList<R>(size), transform)
}

返回结果的数据类型是List,返回结果是列表集合,该集合中的元素类型是R.
R既可以是普通数据类型,也可以是集合类型。

fun testListResult(): Unit {
    val list = listOf(1,2,9)
    // 函数对每个元素进行创建一个list集合操作,此集合的元素是原集合的元素分别加特定数字后的结果
    val ll = list.map { listOf(it + 100, it+110, it+120, it+130) }
    println(list) // 输出:[1, 2, 9]
    println(ll) // 输出:[[101, 111, 121, 131], [102, 112, 122, 132], [109, 119, 129, 139]]
    // 最终的输出结果ll 是一个List集合里嵌套List集合。

    val fll = ll.flatten()  // flatten() 函数用于将嵌套的集合"铺平"
    println(fll) // 输出:[101, 111, 121, 131, 102, 112, 122, 132, 109, 119, 129, 139]

    // flatMap() 函数是 map()和flatten() 两个函数的"复合逻辑"
    val flm = list.flatMap { listOf(it *2, it*3, it*4, it*5) }
    println(flm) // 输出:[2, 3, 4, 5, 4, 6, 8, 10, 18, 27, 36, 45]
}

集合类的过滤函数

filter() 函数

fun testFilterF(): Unit {
    val list = listOf(1,2,5,8,7,9)
    val result = list.filter { it>5 } // 过滤出list中大于5的数
    println(result) // 输出:[8, 7, 9]
}
class Person(var name: String, var age:Int, var sex:String) {
    // override 关键字,重写 toString() 函数
    override fun toString(): String {
        return "Person【name: $name, age: $age, sex:$sex】"
    }
}

fun testFilterF2(): Unit {
    val list = listOf(
        Person("Jack",18,"M"),
        Person("Jhon",21,"M"),
        Person("Lucy",19,"W"),
        Person("Lily",20,"W"),
    )
    val result = list.filter { it.age>19 } // 过滤出年龄大于19的人
    println(result) // 输出:[Person【name: Jhon, age: 21, sex:M】, Person【name: Lily, age: 20, sex:W】]
}

filter() 函数签名:

public inline fun <T> Iterable<T>.filter(predicate: (T) -> Boolean): List<T> {
    return filterTo(ArrayList<T>(), predicate)
}

public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterTo(destination: C, predicate: (T) -> Boolean): C {
    for (element in this) if (predicate(element)) destination.add(element)
    return destination
}

filterIndexed() 函数

fun testFilterIndexedF(): Unit {
    val list = listOf(1,2,5,8,7,9)
    // 带下标过滤list元素
    val result = list.filterIndexed { index, i -> index %2==1 && i < 7 }
    println(result) // 输出:[2]
}

filterIndexed() 函数签名:

public inline fun <T> Iterable<T>.filterIndexed(predicate: (index: Int, T) -> Boolean): List<T> {
    return filterIndexedTo(ArrayList<T>(), predicate)
}

public inline fun <T, C : MutableCollection<in T>> Iterable<T>.filterIndexedTo(destination: C, predicate: (index: Int, T) -> Boolean): C {
    forEachIndexed { index, element ->
        if (predicate(index, element)) destination.add(element)
    }
    return destination
}

集合类的排序函数

倒序排列函数 reversed()

fun testReversed(): Unit {
    val list = listOf(1,2,5,18,27,9)
    val result = list.reversed()
    println(result) // 输出:[9, 27, 18, 5, 2, 1]
		
    val set = setOf(1,2,3,25,15,6,8,28,9)
    val r2 = set.reversed()
    println(r2) // 输出:[9, 28, 8, 6, 15, 25, 3, 2, 1]
}

其实是将集合倒着排列,没有按大小排序。

reversed() 函数签名:

public fun <T> Iterable<T>.reversed(): List<T> {
    if (this is Collection && size <= 1) return toList()
    val list = toMutableList()
    list.reverse()
    return list
}

public actual fun <T> MutableList<T>.reverse(): Unit {
    java.util.Collections.reverse(this)
}

Kotlin的 reversed() 函数是直接调用 java.util.Collections.reverse() 方法。

升序排列函数 sorted()

    val r3 = list.sorted()
    println(r3) // 输出:[1, 2, 5, 9, 18, 27]
    val r4 = set.sorted()
    println(r4) // 输出:[1, 2, 3, 6, 8, 9, 15, 25, 28]

将集合中的元素,按照大小进行升序排列。

sorted() 函数签名:

public fun <T : Comparable<T>> Iterable<T>.sorted(): List<T> {
    if (this is Collection) {
        if (size <= 1) return this.toList()
        @Suppress("UNCHECKED_CAST")
        return (toTypedArray<Comparable<T>>() as Array<T>).apply { sort() }.asList()
    }
    return toMutableList().apply { sort() }
}

public actual fun <T : Comparable<T>> MutableList<T>.sort(): Unit {
    if (size > 1) java.util.Collections.sort(this)
}

Kotlin的 sorted() 函数是直接调用 java.util.Collections.sort() 方法。

集合类的元素去重

distinct() 函数

fun testDistinct(): Unit {
    val list = listOf(1,2,3,5,5,6,8,8,9)
    println(list) // 输出:[1, 2, 3, 5, 5, 6, 8, 8, 9]
    val result = list.distinct()
    println(result) // 输出:[1, 2, 3, 5, 6, 8, 9]
}

distinct() 函数签名:

public fun <T> Iterable<T>.distinct(): List<T> {
    return this.toMutableSet().toList()
}

先将List集合转换成Set集合,以达到去除重复元素的目的,再将Set集合转换成List集合,作为结果返回。

你可能感兴趣的:(Kotlin系列,kotlin,java,开发语言)