一手遮天 Android - kotlin: 数组和集合的常用操作

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

一手遮天 Android - kotlin: 数组和集合的常用操作

示例如下:

/kotlin/Demo5.kt

/**
 * 本例用于演示 kotlin 的数组和集合的常用操作
 *
 * 1、简单的数组操作
 * 2、不可变集合 List, Set, Map;可变集合 MutableList, MutableSet, MutableMap
 * 3、查找某个位置的元素,遍历元素,查找符合指定条件的元素,查找指定范围的元素
 * 4、元素排重,排序,统计,判断是否包含指定元素
 * 5、映射,分组,连接,合并,分拆,分区
 */

package com.webabcd.androiddemo.kotlin

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.webabcd.androiddemo.R
import kotlinx.android.synthetic.main.activity_kotlin_helloworld.*

class Demo5 : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_kotlin_demo5)

        sample1(); // 数组,Range
        sample2(); // 集合 List, Set, Map
        sample3(); // 查找某个位置的元素,遍历元素
        sample4(); // 查找符合指定条件的元素,查找指定范围的元素,元素排重
        sample5(); // 排序
        sample6(); // 统计,判断是否包含指定元素
        sample7(); // 映射,分组
        sample8(); // 连接,合并,分拆,分区
    }

    fun sample1() {
        // 关于数组的一些基础请参见 Demo1.kt 中的相关说明
        val a = arrayOf(1, 2, 3, 4, 5);

        // component1(), component2(), component3(), component4(), component5() - 获取第 n 个元素
        // in - 用于判断指定的元素是否在数组中
        // !in - 用于判断指定的元素是否不在数组中
        appendMessage("${a[0]}, ${a.component1()}, ${ 1 in a}, ${1 !in a}"); // 1, 1, true, false

        // 通过 .. 定义一个 Range(范围),这个范围大于等于左边的,小于等于右边的
        var b = 1..3 // 这个范围包括 1 2 3
        // 通过 in 判断某个数是否在指定范围中
        var c = 1 in b
        // 通过 !in 判断某个数是否不在指定范围中
        var d = 3 !in b
        appendMessage("$c, $d") // true, false
    }

    fun sample2() {
        // 实例化 List 集合
        val a: Array<Any> = arrayOf("1", "2", 3, 4, 5);
        val b: List<Any> = listOf(a);
        val c: List<Any> = listOf("1", "2", 3, 4, 5);
        val d: List<String> = listOf<String>("1", "2", "3", "4", "5");

        // 实例化 Set 集合(Set 和 List 的区别就是 Set 不可重复)
        val e = setOf<Int>(3, 2, 5, 1, 2, 3, 4); // 3 2 5 1 4
        val f: Set<Int> = setOf(3, 2, 5, 1, 2, 3, 4); // 3 2 5 1 4
        var eString = ""
        for(item in e) {
            eString += item;
        }
        appendMessage("$eString");

        // 实例化 Map 集合(字典表)
        val g: Map<String, String> = mapOf("k1" to "v1" , "k2" to "v2");
        val h = mapOf<Int, String>(1 to "v1" , 2 to "v2")
        appendMessage("${g["k1"]}, ${h[1]}"); // v1, v1

        // 上面声明的 List, Set, Map 都是不可变集合(即不能添加元素,不能删除元素,不能修改元素)
        // 如果要对集合增删改的话需要用 MutableList, MutableSet, MutableMap
        // 增删改的方法就是 add(), remove(), list[i] = xxx, set[i] = xxx, map[key] = value 之类的
        // 可以通过类似 toXXX() 的方法来做各种类型的转换
        var i: MutableList<Int> = mutableListOf(1, 2, 3);
        var j: MutableSet<Int> = mutableSetOf(1, 2, 3);
        var k: MutableMap<String, String> = mutableMapOf("k1" to "v1" , "k2" to "v2")
    }

    fun sample3() {
        // component1(), component2(), component3(), component4(), component5() - 获取第 n 个元素
        // elementAt(), indexOf(), indexOfFirst{}, indexOfLast{}
        // first(), first{}, firstOrNull(), firstOrNull{}, last(), last{}, lastOrNull(), lastOrNull{}, single(), single{}, singleOrNull(), singleOrNull{}
        // 上面 single 和 first 的区别是,如果匹配到多个结果的话,那么 single 是会抛出异常的

        // elementAtOrNull(), getOrNull() - 根据索引获取到的元素越界了,则返回 null
        // elementAtOrElse(index, {...}), getOrElse(index, {...}) - 根据索引获取到的元素越界了,则返回指定表达式的运算结果
        // forEachIndexed{}, forEachIndexed{} - 遍历元素
        val a = listOf(1, 2, 3, 4, 5);
        var aString1 = "";
        a.forEach{ aString1 += it };
        var aString2 = "";
        a.forEachIndexed { index, value -> aString2 += index; aString2 += value }
        appendMessage("${a.elementAtOrNull(5)}, ${a.elementAtOrElse(5, { it * 100 })}, $aString1, $aString2"); // null, 500, 12345, 0112233445
    }

    fun sample4() {
        val a = listOf(1, 2, 3, 4, 5, 5, 4, 3, 2, 1);

        // filter{} - 检索符合指定条件的数据,类似的还有 filterIndexed{}, filterNot{}, filterNotNull{}
        var b = a.filter { it % 2 == 0 }; // [2,4,4,2]

        // take() - 获取前 n 条数据,类似的有 takeLast()
        // takeWhile{} - 按顺序一条一条地拿数据,直到 while 条件为假就退出,类似的有 takeLastWhile{}
        var c = a.take(3); // [1,2,3]
        var d = a.takeWhile { it < 3 }; // [1,2]

        // drop() - 删除前 n 条数据,类似的有 dropLast();
        // dropWhile{} - 按顺序一条一条地删数据,直到 while 条件为假就退出,类似的有 dropLastWhile{}
        var e = a.drop(3); // [4,5,5,4,3,2,1]
        var f = a.dropWhile { it < 3 }; // [3,4,5,5,4,3,2,1]

        // distinct() - 直接排重
        // distinctBy{} - 根据表达式结果排重
        var g = a.distinct(); // [1,2,3,4,5]
        var h = a.distinctBy { it % 2 == 0 }; // [1,2]

        // slice() - 获取指定索引范围的数据
        var i = a.slice(7..9); // [3,2,1]

        appendMessage("$b, $c, $d, $e, $f, $g, $h, $i");
    }

    fun sample5() {
        // reversed() - 反序
        // sorted(), sortedBy{}, sortedDescending(), sortedByDescending{}

        val a = listOf(1, 2, 3, 4, 5);
        var b = a.sortedByDescending { it % 2 };
        var bString = "";
        b.forEach{ bString += it };
        appendMessage("$bString"); // 13524
    }

    fun sample6() {
        val a = listOf(1, 2, 3, 4, 5);

        // any() - 是否包含元素
        // any{} - 是否包含符合指定条件的元素
        // all{} - 集合中是否所有元素都符合指定的条件
        // none() - 是否为空集合
        // none{} - 集合中是否所有元素都不符合指定的条件
        // count(), count{} - 统计符合条件的元素的数量
        // max(), maxBy{}, min(), minBy{}, sum(), sumBy{}, sumByDouble{}, average()
        var b = a.any { it > 3 }; // true
        var c = a.count {it > 3}; // 2
        var d = a.all {it > 3}; // false
        var e = a.sumBy { if (it % 2 == 0) it else 0 }; // 6
        var f = a.average(); // 3.0

        // reduce{} - 从集合第一个元素到最后一个元素的累计操作,类似的还有 reduceIndexed{}, reduceRight{}, reduceRightIndexed{}
        // fold(){} - 与 reduce{} 类似,只不过 fold(){} 可以有个累计初始值,类似的还有 foldIndexed{}, foldRight{}, foldRightIndexed{}
        var g = a.reduce { result, next -> result + next }; //15
        var h = a.fold(100) { result, next -> result + next }; // 115
        appendMessage("$b, $c, $d, $e, $f, $g, $h");

        // contains() - 判断数组是否包含指定元素
        // in - 判断指定的元素是否在数组中
        // !in - 判断指定的元素是否不在数组中
        appendMessage("${a.contains(1)}, ${1 in a}, ${1 !in a}"); // true, true, false
    }

    fun sample7() {
        val a = listOf(1, 2, 3, 4, 5);

        // map{} - 把每个元素按照指定的表达式进行计算,然后将结果组成一个新的集合,类似的还有 mapNotNull{}, mapIndexed{}, mapIndexedNotNull{}
        // flatMap{} - 类似于 map{},只不过 map{} 是合并多个转换后的元素为一个集合,而 flatMap{} 是合并多个转换后的集合为一个集合
        // groupBy{} - 按指定条件分组,返回的是一个 Map<K,List<T>>类型的集合
        var b = a.map { it * 2 }; // [2,4,6,8,10]
        var c = a.flatMap { listOf(0, 999, it * 2) }; // [0,999,2,0,999,4,0,999,6,0,999,8,0,999,10]
        var d = a.groupBy { if ( it % 2 == 0) "even" else "odd" }; // {odd=[1,3,5],even=[2,4]}

        appendMessage("$b, $c, $d");
    }

    fun sample8() {


        /*
        plus() : 合并两个集合中的元素,组成一个新的集合。也可以使用符号+
zip : 由两个集合按照相同的下标组成一个新集合。该新集合的类型是:List<Pair>
unzip : 和zip的作用相反。把一个类型为List<Pair>的集合拆分为两个集合。看下面的例子
partition : 判断元素是否满足条件把集合拆分为有两个Pair组成的新集合。
         */
        val a = listOf(1, 2, 3, 4, 5);
        val b = listOf("a", "b", "c");

        // 通过 + 或 plus 连接两个集合(其实 plus() 就是 +)
        var c = a + b; // [1,2,3,4,5,a,b,c]

        // zip() - 按照相同的索引合并两个集合,两个集合的元素的数量不一样时则自动丢弃多出来的元素,合并后的新集合的类型是 List<Pair>
        // zip(){} - 可以按指定的表达式合并两个集合
        var d = a.zip(b); // [(1,a),(2,b),(3,c)]
        var d1 = d[0].first; // 1
        var d2 = d[0].second; // a
        var e = a.zip(b) { it1, it2 -> it2 + it1}; // [a1,b2,c3]

        // unzip() - 与 zip() 相反,用于把一个 List<Pair> 分拆为两个集合
        var f = d.unzip(); // ([1,2,3],[a,b,c])
        var f1 = f.first; // [1,2,3]
        var f2 = f.second; //[a,b,c]

        // partition{} - 分区,用于将集合转换为 Pair 对象(first 是符合指定条件的,second 是不符合指定条件的)
        var g = a.partition { it % 2 == 0  }; // ([2,4],[1,3,5])
        var g1 = g.first; // [2,4]
        var g2 = g.second; // [1,3,5]

        appendMessage("$c, $d, $d1, $d2, $e, $f, $f1, $f2, $g, $g1, $g2");

    }

    fun appendMessage(message: String) {
        textView1.append(message);
        textView1.append("\n");
    }
}

/layout/activity_kotlin_demo5.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

</LinearLayout>

项目地址 https://github.com/webabcd/AndroidDemo
作者 webabcd

posted @ 2021-05-31 12:09  webabcd  阅读(702)  评论(0编辑  收藏  举报