乐趣区

关于android:Kotlin-集合的变换与聚合

一、前言

<font face= 黑体 > 在 Kotlin 高阶函数与内联函数 中咱们曾经将 Kotlin 的 高阶函数 内联函数 讲完了,明天咱们来讲 Kotlin 的 汇合变换与聚合

二、汇合变换与聚合

2.1、汇合的变换操作

<font face= 黑体 > 对于汇合来说,最常见的应用形式就是对汇合进行遍历,咱们来看一下 Java 和 Kotlin 的遍历汇合代码:
Java:

// 一般的 for 循环遍历
for(int i = 0; i <= 10; i++) {System.out.println(i);
}

// for each 遍历
for(int e : list) {System.out.println(e);
}

// forEach 函数
list.forEach((e) - > {System.out.println(e);
});

Kotlin:

// 一般的 for 循环遍历
for(i in 0 .. 10) {println(i)
}

// for each 遍历
for(e in list) {println(e);
}

// forEach 函数
list.forEach {println(it);
}

<font face= 黑体 > 在下面的 forEach 函数外面不能 continue 或者 break,然而咱们有须要 break 和 continue 的需要要怎么办呢?其实咱们有专用的办法来解决这样的需要,就是汇合的 映射操作(Java 在 8 的时候也引入了这些操作,叫 流 Stream),如下:

函数名 阐明
filter 保留满足条件的元素
map 汇合中的所有元素 —— 映射到其余元素形成新汇合
flatMap 汇合中的所有元素 —— 映射到新汇合并合并这些汇合失去新汇合

2.1.1、filter 操作

<font face= 黑体 > 比方咱们要从汇合 [1, 2, 3, 4] 中将所有的偶数筛选进去,就能够用 filter 操作来实现,如下:

Java:

 list.stream()
     .filter(e -> e % 2 == 0);

Kotlin:

list.filter {it % 2 == 0}

2.1.2、map 操作

<font face= 黑体 > 比方咱们要把汇合 [1, 2, 3, 4] 中的所有元素乘以 2,变成一个新汇合,就能够用 map 操作来实现,如下:

Java:

 list.stream()
     .map(e -> e * 2);

Kotlin:

list.map {it * 2}

<font face= 黑体 > 下面的 Kotlin 代码还能够写成上面这样:

list.asSequence().map { it * 2}

<font face= 黑体 > 这两种写法区别次要是汇合的操作是饿汉式的还是懒汉式的,如果加上 asSequence 的话,汇合的操作就变成了懒序列了。咱们通过上面的代码来解释这两种形式:

Java:

List<Integer> list = new ArrayList<>();
list.addAll(Arrays.asList(1, 2, 3, 4));

list.stream()
        .filter(e -> {System.out.println("filter:" + e);
        return e % 2 == 0;
        })
        .map(e -> {System.out.println("map:" + e);
        return e * 2 + 1;
        })
        .forEach(e -> {System.out.println("forEach:" + e);
        });

Kotlin:

val list = listOf(1, 2, 3, 4)
list.asSequence()
     .filter {println("filter: $it")
         it % 2 == 0
     }.map {println("map: $it")
         it * 2 + 1
     }.forEach {println("forEach: $it")
     }

<font face= 黑体 > 打印后果如下所示:

<font face= 黑体 > 从打印后果能够看出,懒序列的执行形式是汇合外面的 1 走一遍残缺的流程,走完之后 2 持续走一遍残缺的流程 …,然而 1 呢在 filter 外面判断是不是偶数就不满足了,而后就是 2 走一遍残缺流程,2 是满足 filter 的过滤的,所以 2 就到了 map 外面映射成了 5,而后在 forEach 中输入了,3 和 4 都是同样的流程。

<font face= 黑体 > 如果咱们把 asSequence() 去掉,就变成了饿汉式,代码如下:

val list = listOf(1, 2, 3, 4)
list
    .filter {println("filter: $it")
        it % 2 == 0
    }.map {println("map: $it")
        it * 2 + 1
    }.forEach {println("forEach: $it")
    }

<font face= 黑体 > 从打印后果能够看出,饿汉式在调用 filter 的时候马上就会将汇合全副过滤一遍,而后过滤之后的在去执行 map,等所有元素 map 操作都执行好之后,在执行 forEach。

2.1.3、flatMap 操作

<font face= 黑体 >flatMap 操作能够看上面的图解:

<font face= 黑体 >flatMap 的操作就是将一个元素映射成汇合,而后再将这些汇合合并起来。

2.2、汇合的聚合操作

<font face= 黑体 > 汇合除了有上述的变换操作外,汇合还有聚合操作,如下:

函数名 阐明
sum 所有元素求和
reduce 将元素顺次按规定聚合,后果与元素类型统一
fold 给定初始化值,将元素按规定聚合,后果与初始化值类型统一

<font face= 黑体 >Kotlin 的汇合的聚合操作相比来讲没有变换操作重要,这里我就举个 fold 函数的例子吧,如下:

// 计算过程为 10 + 1 + 2 + 3, 等于 16
val foldResult1 = arrayOf(1, 2, 3).fold(10, { a, b -> a + b}) 
println(foldResult1)

// 计算过程为 10 * 1 * 2 * 3, 等于 60
val foldResult2 = arrayOf(1, 2, 3).fold(10, { a, b -> a * b})
println(foldResult2)

<font face= 黑体 >fold 函数的操作如下:

  1. <font face= 黑体 > 第一次执行时, 由初始值 10 作为参数 a,由汇合中第 0 个元素作为参数 b;
  2. <font face= 黑体 > 第二次执行时, 第一次执行的返回值作为参数 a,由汇合中第 1 个元素作为参数 b;
  3. <font face= 黑体 > 顺次类推 …;
  4. <font face= 黑体 > 最终将后果返回。

三、小结

<font face= 黑体 > 本篇博客次要讲了 Kotlin 中的 汇合的变换与聚合 ,下一节咱们讲 Kotin 的 SAM 转换 罕用高阶函数

四、源码

源码 已上传至 github,有须要能够间接下载。

退出移动版