一文弄明白链式调用和非链式调用的区别
定义
两者本质都是对数据进行处理分类,得到最终符合条件的数据
但是他们之间也有差别
- 链式调用是以链表为单位,每次判断都会生成新的链表
- 非链式调用是通过链表的节点为单位,不会生成新的链表,同时遍历链表的一部分已经满足结果时,终止遍历,节省消耗
所以非链式调用能有更好的时间和空间复杂度,推荐使用
同时,在 Java ,Kotlin 等编程语言中,也有封装的一些非链式调用的类,通过这些类,也能让我们的代码更加的优雅,减少后期维护的复杂度
在下面的章节中,我们可以通过示例代码很清晰的看出来
实现的差别
如有 1 到 20 的整数,我们想得到 2 个大于 10 的偶数 所以,我们只需要依次判断三个条件即可
- 大于 10
- 是偶数
- 取 2 个结果
下面是链式调用和非链式调用对此的实现,从中我们可以发现他们的差别
链式调用的实现
以链表为单位进行处理,每次都需要完整遍历集合并将中间结果缓存,下一次调用依赖上一次调用缓存的结果
public List<Integer> dealCollection(List<Integer> list) {
List<Integer> evenList = new ArrayList<>();
for (Integer integer : list) {
//👇 筛选出偶数
if (integer % 2 == 0) {
evenList.add(integer);
}
}
List<Integer> bigList = new ArrayList<>();
for (Integer integer : evenList) {
//👇 从偶数中筛选出大于10的数
if (integer > 10) {
bigList.add(integer);
}
}
List<Integer> numList = new ArrayList<>();
for (Integer integer : bigList){
//👇 选出小于 2 的
if (numList.size()<=2){
numList.add(integer);
}
if (numList.size() == 2){
break;
}
}
//👇 返回筛选结果列表
return numList;
}
可以发现每次进行处理时,我们都需要一个额外的链表存储结果,这个会导致额外的空间复杂度 每次处理都需要遍历整个链表,时间复杂度大 同时,因为这里我们只需要 2 个值,遍历整个链表会造成更大的额外时间复杂度
非链式调用的实现
以链表的每个节点为单位进行处理
fun testSequence() {
val result : Sequence<Int> = (0..20)
.asSequence()//转换为sequence
.filter { it>10 }
.filter {
print(" $it")
it % 2 == 0//过滤偶数
}.take(2)
result.count()//调用 result 的逻辑,没有这个上面的代码不会执行
// 11 12 13 14 [12, 14]
}
}
- 只做最少的操作
- 不暂存数据,不进行多次遍历
从输出的结果 11 12 13 14 [12, 14]
看,只做了最少的操作,遍历到 14 就满足了,我们就不需要遍历后面的了
现有的类
- kotlin :
Sequence
- Java :
Stream
- Android:
FluentIterable
Java Stream
private static void extracted() {
ArrayList<Integer> list = new ArrayList<>();
for (int a = 0; a < 20; a++) {
list.add(a);
}
Stream<Integer> stream = null;
stream = list.stream();
Stream s = stream.filter(value -> {
return value > 10; // 大于10
}).filter(value -> {
System.out.print(" " + value);
return value % 2 == 0; // 偶数
}).limit(2);
System.out.println(" " + Arrays.toString(s.toArray()));
// 11 12 13 14 [12, 14]
}
kotlin Sequence
fun testSequence() {
val result : Sequence<Int> = (0..20)
.asSequence()//转换为sequence
.filter { it>10 }
.filter {
print(" $it")
it % 2 == 0//过滤偶数
}.take(2)
result.count()//调用 result 的逻辑,没有这个上面的代码不会执行
// 11 12 13 14 [12, 14]
}
参考文档
转载自:https://juejin.cn/post/7361284455534854179