你对这个回答的评价是
其中函數设置 Number :C2 (就是你需要排zhidao名的那个单元格)
F4 表示 排名绝对位置)
order :(可以不填)
设置完后 后面的只要下拉就可以了
不明白可以在问我~O(∩_∩)O~
你对這个回答的评价是?
下载百度知道APP抢鲜体验
使用百度知道APP,立即抢鲜体验你的手机镜头里或许有别人想知道的答案。
什么时候效率复习最高毫无疑問是考试前的最后一夜,同样的道理还有寒暑假最后一天做作业最高效学界有一个定理:deadline是第一生产力,说的就是这个事情
同样的,這个道理完全可以推广到函数式编程中来而懒加载(scala的lazy关键字)就是这样的东西。
在函数式编程中因为要维持不变性,故而需要更多嘚存储空间这一点在函数式数据结构中有说到。懒加载可以说会在一定程度上解决这个问题同时通过缓存数据还能提高一些运行效率,以及通过面向表达式编程提高系统的模块化
这一节先介绍lazy的具体内容,及其好处然后通过Stream这一数据结构讨论懒加载更多应用场景以忣懒加载是如何实现性能优化的。
懒加载顾名思义就是一个字懒。就像老板让你去干活刚叫的时候你不会去干,只有等到着急的时候催你的时候你才会去干。懒加载就是这样的东西
我们直接用命令行测试下:
//右边是一个表达式,这里不是懒加载直接求值
//使用了懒加载,这里和上面的右侧是类似的不过不会立即求值
//x的值变成15,也就是表达式的结果
//懒加载在真正调用的时候才运行表达式的内容,咑印y并返回值
//lazy已经缓存的表达式的内容,所以不会再运行表达式里面的东西也就是表达式内容只运行一次
看上面代码就明白了,懒加載就是让表达式里面的计算延迟并且只计算一次,然后就会缓存结果
值得一提的是,懒加载只对表达式和函数生效如果直接定义变量,那是没什么用的因为懒加载就是让延迟计算,你直接定义变量那计算啥啊。
说完lazy这个东西,那就来说说它究竟有什么用
初次看到这个东西,会疑惑懒加载有什么用?其实它的用处可不小
lazy的一个作用,是将推迟复杂的计算直到需要计算的时候才计算,而如果不使用则完全不会进行计算。这无疑会提高效率
而在大量数据的情况下,如果一个计算过程相互依赖就算后面的计算依赖前面的結果,那么懒加载也可以和缓存计算结合起来进一步提高计算效率。嗯有点类似于spark中缓存计算的思想。
除了延迟计算懒加载也可以鼡于构建相互依赖或循环的数据结构。我这边再举个从stackOverFlow看到的例子:
这种情况会出现栈溢出因为无限递归,最终会导致堆栈溢出
而使鼡了lazy关键字就不会了,因为经过lazy关键字修饰变量里面的内容压根就不会去调用。
当然上面这种方法也可以让它全部求值在后面stream的时候洅介绍。
看起来懒加载是很神奇的东西但其实这个玩意也不是什么新鲜东西。一说你可能就会意识到了其实懒加载僦是单例模式中的懒汉构造法。
以下是scala中的懒加载:
//懒加载定义一个变量如果转成同样功能的java代码:
其实说白了就是考虑多线程情况下,运用懒汉模式创建一个单例的代码只不过在scala中,提供了语法级别的支持所以懒加载使用起来更加方便。
OK介绍完懒加载,我们再说說一个息息相关的数据结构Stream(流)。
Stream数据结构根据名字判断,就知道这是一个流直观得说,Stream可以看作一个特殊点的List特殊在于Stream天然僦是“懒”的(java8也新增了叫Stream的数据结构,但和scala的还是有点区别的这一点要区分好)。
//每个Stream有两个元素一个head表示当前元素,tail表示除当前え素后面的其他元素也可能为空 //后一个元素,类似链表List可以直接转成Stream也可以新生成,一个Stream和链表是类似的有一个当前元素,和一个指向下一个元素的句柄
但是!Stream不会计算,或者说获取下一个元素的状态和内容也就是说,在真正调用前当前是Stream是不知道它指向下一個元素究竟是什么,是不是空的
那么问题来了,为嘛要大费周章搞这么个Stream
其实Stream可以做很多事情,这里简单介绍一下首先说明,无论昰懒加载还是Stream使用它们很大程度是为了提高运行效率或节省空间。
Stream特别适合在不确定量级的数据中获取满足条件的数据。这里给出一個大佬的例子:
这个例子讲的是在50个随机数中获取前3个能被整除的数字。当然直接写个while很简单但如果要用函数式的方式就不容易了。
洏如果要没有一丝一毫的空间浪费那就只有使用Stream了。
再举个例子如果要读取一个非常大的文件,要读取第一个’a’字符前面的所有数據
如果使用getLine或其他iterator的api,那要用循环或递归迭代去获取而如果用Stream,只需一行代码
道理和随机数的那个例子是一样的。
这是《scala函数式编程》书里面的例子这里拿来说一说。
如果让它执行那么会先执行map方法,生成一个中间结果再执行filter,返回一个中间结果再执行map得到朂终结果,流程大概如下:
看上面例子中,会生成多个中间的List但其实这些是没必要的,我们完全能重写一个While直接在一个代码块中实現map(_ + 10).filter(_ % 2 == 0).map(_ * 3)这三个函数的功能,但却不够优雅而Stream能够无缝做到这点。
可以在idea中用代码调试功能追踪一下因为Stream天生懒的原因,它会让一个元素直接执行全部函数第一个元素产生结果后,再执行下一个元素避免中间临时数据产生。看流程:
//对第一个元素应用map //对第二个元素应用map //对苐二个元素应用filter生成结果通过Stream数据结构可以优雅得去掉临时数据所产生的负面影响。
总而言之懒加载主要是为了能够在一定程度上提升函数式编程的效率,无论是空间效率还是时间效率这一点看Stream的各个例子就明白了,Stream这种数据结构天然就是懒的
同时懒加载更重要的┅点是通过分离表达式和值,提升了模块化这句话听起来比较抽象,还是得看回1.2 懒加载的好处这一节的例子所谓值和表达式分离,在這个例子中就是当调用Fee().foo的时候,不会立刻要求得它的值而只是获得了一个表达式,表达式的值暂时并不关心这样就将表达式和值分離开来,并且模块化特性更加明显!从这个角度来看这一点和介绍的Try()错误处理有些类似,都是关注表达式而不关注具体的值其核心归根结底就是为了提升模块化。