假设一个场景
需要在50个随机数中找到前两个可以被3整除的数字。
听起来很简单,我们可以这样来写:
一个产生50个随机数的函数;
一个检查某数字是否能被3整除的函数;
最后,对含有50个随机数的List做filter操作,找到其中所有能够被3整除的数字,取其中前两个。
把这段代码在Scala的console里面跑一下,结果是这样的:
其最终结果固然是没有问题,找到了48和27这两个数字。但是非常明显的可以看出,isDivisibleBy3被调用了50次,找到了远多于两个的能被3整除的数字,但是最后我们只关心其中前两个结果。
这似乎有点浪费,做了很多多余的运算。
对于这个例子来说,这还没什么,我们的List很小,判断整除于否也不是什么耗时操作。
但是如果List很大,filter时所做的运算很复杂的话,那这种做法就不可取了。
现有解法的优缺点
这行代码有一个优点:
用描述性、声明性的语言描述了我们要做的事是什么,而无需描述怎么做。我们只需说先用filter过滤一下,然后拿前两个,整件事就完成了。
但是它同时也有一个缺点:
做了多余的运算,浪费资源,而且这个缺点会随着数据量的增大以及计算复杂度的增加而更为凸显。
试着解决其缺点
解决多余运算的思路很简单,不要过滤完整个List之后再取前两个。而是在过滤的过程中如果发现已经找到两个了,那剩下的就忽略掉不管了。
顺着这个思路很容易写出如下很像Java的代码:
创建一个可变的List,开始遍历随机数,找到能被3整除的就把它塞进可变List里面去,找够了两个就返回。