最近加入了一个有趣的年轻同事,提交了很多代码。查看git记录,发现代码已经通过使用java8的大量语法特性进行了重构。最常用的有map,flatMap等等。
但是其他朋友不愿意。虽然有人觉得代码变得容易理解,但更多的人觉得代码变得很晦涩。
就像:脱裤子放屁,干的不止一件事。
根据层次,这些职能的范围可以分为三类。几乎无处不在。
不要过度使用
我不知道这些函数是什么时候流行起来的,但它们肯定和函数编程有着密切的关系。Scala好像是2004年开始的。
没什么神奇的。都是语法糖,作用是让你的程序更简洁。如果你愿意,你可以用更多的代码来完成。不要为了炫技而刻意使用。如果用不好,效果会很负面。比如Java,不是函数式编程语言,所以lambda只是辅助;如果你用java写Lisp代码,那只会不伦不类。
但是,语言要整合,因为这是趋势。我们不看他们背后的设计,只看他们从api的语义表示水平表达了什么。
我们先来看看共性(注意:逻辑上的共性并不适合所有的场景),然后拿一些典型的实现来看看这个星球上程序员的表现。
这些抽象的概念
这些函数的对象被称为流。小溪是一种什么东西?请原谅我用一些不专业的话来解释。
它实际上是一个简单的数组,无论是语言还是分布式数据结构。有时候真的是一个简单的数组,有时候是一个存在于多台机器中的分布式数组。在下文中,我们统称为数组流。
我们简单地分为两类。
语言层:比如Java的Stream分布式层:比如Spark的RDD
他们都有以下要点。
函数可以用作参数
c语言当然没问题,函数可以作为指针传入。但不久前,在java中,这必须马上实现(使用java中的类概念来模拟函数,您会看到许多奇怪的Java类,如Func1和Func0)。
函数作为参数是使代码简洁的必要条件。我们通常的编程方法大多是按顺序执行一些操作。
Array = new Array()Array = func 1(Array)if(func 2(Array)){ Array = func 3(Array)} Array = func 4(Array)
而且如果函数可以作为自变量,我可以尽量平铺操作。最后还得翻译成上面的语句来执行。
array = new Array()array.stream()。map(func1)。过滤器(func2)。flatMap(func3)。已排序(func4)...
编程模式完全变了,函数有语义。
顺序并行
如果我们的数组流太大,单台计算机有两种方式:顺序处理和并行处理。
一般可以通过并行功能进入并行处理模式。对于大多数本地操作,并行化不一定很快。
在java中使用ForkJoin,线程速度,你知道…
但是对于分布式数据流,是并行的,所以这个参数意义不大。
功能类型
一般来说,作用于数据流的功能可以分为两类。
转换。转化动作。行为
转化,典型特征就是懒。
只有执行了动作,它才会真正参与操作。因此,您可以将这些转换操作视为一组缓冲操作。地图、flatMap等典型功能。它们像串串一样串在一起,等着被砸碎。
行动。当代码真正被触发运行时,上面的一系列转换也会像闸门一样泛滥下来。典型的如减函数,就是这样。
以上描述并不完全正确。比如python的map可以在执行后输出结果。让人没面子。
地图缩小
说到map和reduce,大家都想到了hadoop。然而,这不仅仅是大数据中的一个概念。
对于他们的概念,我们只介绍下面两行。
地图
将传入函数依次应用于序列的每个元素,并将结果作为新的数组流返回。
减少
Reduce类似于递归概念。最终会降低到一个值。看这个公式:)
reduce([p1,p2,p3,p4],fn) = reduce([fn(p2,p4),fn(p1,p3)]
我们来看看谷歌的经典论文。
《地图简化:简化数据》
《大型集群上的处理》
https://ai.google/research/pubs/pub62
可以去看看吗?:)
地图平面地图
经常用到这两个函数。它们有以下不同之处:
地图
通过使用提供的函数,以一对一的对应关系执行数组流中的每个值一次。获取具有相同元素数量的数组流。
平面地图
平就是平。它使用提供的函数执行数组流中的每个值一次,并且一一对应。获取具有相同元素的数组流。但是,里面的元素也是一个子数组流。在将这些子阵列合并成一个阵列后,元素的数量将不同于原始阵列流的数量。
程序员的表现
java8中的八种流
自从java8以来,增加了一个新的抽象,叫做Stream: stream。有了lambda语法,可以让代码特别清爽干净(如果发现了什么,很快就会变成Scala)。
一个非常好的指南:
https://stackify.com/streams-guide-java-8/
星火的RDD操作
spark的核心数据模型是RDD,它是一个有向无环图。它表示一个不可变的、可分区的集合,其元素可以并行计算。
它是分布式的,但是我们可以看看下一个WordCount的例子。
JavaRDDtextFile = sc . TextFile(HDFS://...);
JavaPairRDDcounts = textFile
。flat map(s-arrays . aslist(s . split())。迭代器())
。mapToPair(word - new Tuple2(word,1))
。reduceByKey((a,b)-a+b);
counts.saveAsTextFile(hdfs://...);
好熟悉的Api!你一定在Hadoop里看到过。
Flink's DataStream
Flink程序是执行分布式集合变换(例如,过滤、映射、更新状态、连接、分组、定义窗口、聚合)的例行程序。Flink中的DataStream程序是在数据流上实现的转换。
让我们也来看看它的一段代码。
DataStreamtuple2 counts =//将包含:(word,1)text . flat map(new Tokenizer())//的行成对分割(2元组),按元组字段0分组,并合计元组字段1.keyBy(0)。sum(1);
卡夫卡流的运作
卡夫卡已经成为分布式流媒体计算平台。他抽象出了一个KStream和KTable,这两个和Spark的RDD类似,操作类似。
KStream可以看作是KTable的changlog,数据流中的每一条记录都对应着数据库中的每一次更新。
让我们来看一段代码。
KTablewordCounts =文本行
。flat mapvalues(value-arrays . aslist(value . tolowercase()。拆分(W+)))
。groupBy((键,值)-值)
。count();
wordCounts.toStream()。to(streams-wordcount-output,Producted . with(StringSerde,LongSerde));
RxJava
RxJava是基于观察者模式的异步任务框架,在Android开发中经常用到(越来越多的用在服务器端)。
RxJava在语言层面做了一些创新,也有一些忠实的信徒。
语言层面的Lambda
当然,Haskell这种自然的函数式编程语言也有自己的光环。但是其他语言,包括脚本语言和编译语言,也吸收了这些经验。
它们统称为λ。
计算机编程语言
作为最流行的脚本语言,python也有它的lambda语法。最基本的功能如映射、约简、过滤也是存在的。
爪哇岛
Js不能掉,比如Array.prototype.*()。它拥有它应该拥有的一切。
还有很多,就不一一列举了。换句话说,这些功能可以申请专利吗?我很喜欢,虽然很少用。
1.《flatmap 到处是map、flatMap,啥意思?》援引自互联网,旨在传递更多网络信息知识,仅代表作者本人观点,与本网站无关,侵删请联系页脚下方联系方式。
2.《flatmap 到处是map、flatMap,啥意思?》仅供读者参考,本网站未对该内容进行证实,对其原创性、真实性、完整性、及时性不作任何保证。
3.文章转载时请保留本站内容来源地址,https://www.lu-xu.com/tiyu/714889.html